DEV: [gjs-codemod] Convert automation/styleguide/other to gjs

Co-authored-by: Jarek Radosz <jarek@cvx.dev>
This commit is contained in:
David Taylor
2025-04-14 15:36:16 +01:00
parent 3462113bd4
commit 7b2b08cf89
144 changed files with 4859 additions and 3715 deletions

View File

@ -794,3 +794,7 @@ export function isPrimaryTab() {
} }
}); });
} }
export function optionalRequire(path, name = "default") {
return require.has(path) && require(path)[name];
}

View File

@ -1,9 +1,12 @@
import Component from "@ember/component"; import Component, { Input } from "@ember/component";
import { hash } from "@ember/helper";
import { tagName } from "@ember-decorators/component"; import { tagName } from "@ember-decorators/component";
import PluginOutlet from "discourse/components/plugin-outlet";
import icon from "discourse/helpers/d-icon";
@tagName("") @tagName("")
export default class Checkbox extends Component {} export default class Checkbox extends Component {
<template>
<label class="wizard-container__label"> <label class="wizard-container__label">
<PluginOutlet <PluginOutlet
@name="wizard-checkbox" @name="wizard-checkbox"
@ -17,7 +20,7 @@ export default class Checkbox extends Component {}
/> />
<span class="wizard-container__checkbox-slider"></span> <span class="wizard-container__checkbox-slider"></span>
{{#if this.field.icon}} {{#if this.field.icon}}
{{d-icon this.field.icon}} {{icon this.field.icon}}
{{/if}} {{/if}}
<span class="wizard-container__checkbox-label"> <span class="wizard-container__checkbox-label">
{{this.field.placeholder}} {{this.field.placeholder}}
@ -29,3 +32,5 @@ export default class Checkbox extends Component {}
@outletArgs={{hash disabled=this.field.disabled}} @outletArgs={{hash disabled=this.field.disabled}}
/> />
</label> </label>
</template>
}

View File

@ -1,5 +1,7 @@
import Component from "@ember/component"; import Component, { Input } from "@ember/component";
import { on } from "@ember/modifier";
import { action, set } from "@ember/object"; import { action, set } from "@ember/object";
import icon from "discourse/helpers/d-icon";
export default class Checkboxes extends Component { export default class Checkboxes extends Component {
init(...args) { init(...args) {
@ -30,8 +32,8 @@ export default class Checkboxes extends Component {
} }
this.set("field.value", newFieldValue); this.set("field.value", newFieldValue);
} }
}
<template>
{{#each this.field.choices as |c|}} {{#each this.field.choices as |c|}}
<div class="checkbox-field-choice {{this.fieldClass}}"> <div class="checkbox-field-choice {{this.fieldClass}}">
<label id={{c.id}} value={{c.label}}> <label id={{c.id}} value={{c.label}}>
@ -42,9 +44,11 @@ export default class Checkboxes extends Component {
{{on "click" (action "changed")}} {{on "click" (action "changed")}}
/> />
{{#if c.icon}} {{#if c.icon}}
{{d-icon c.icon}} {{icon c.icon}}
{{/if}} {{/if}}
{{c.label}} {{c.label}}
</label> </label>
</div> </div>
{{/each}} {{/each}}
</template>
}

View File

@ -2,6 +2,8 @@ import Component from "@ember/component";
import { classNameBindings } from "@ember-decorators/component"; import { classNameBindings } from "@ember-decorators/component";
@classNameBindings(":wizard-image-preview", "fieldClass") @classNameBindings(":wizard-image-preview", "fieldClass")
export default class Generic extends Component {} export default class Generic extends Component {
<template>
<img src={{this.field.value}} class={{this.fieldClass}} /> <img src={{this.field.value}} class={{this.fieldClass}} />
</template>
}

View File

@ -446,6 +446,17 @@ export default class PreviewBase extends Component {
unreadTextX + ctx.measureText(unreadText).width + headerMargin * 2.0; unreadTextX + ctx.measureText(unreadText).width + headerMargin * 2.0;
ctx.fillText(topText, topTextX, pillButtonTextY); ctx.fillText(topText, topTextX, pillButtonTextY);
} }
<template>
<div class="wizard-container__preview">
<canvas
width={{this.elementWidth}}
height={{this.elementHeight}}
style={{this.canvasStyle}}
>
</canvas>
</div>
</template>
} }
function loadImage(src) { function loadImage(src) {
@ -457,12 +468,3 @@ function loadImage(src) {
img.src = getUrl(src); img.src = getUrl(src);
return new Promise((resolve) => (img.onload = () => resolve(img))); return new Promise((resolve) => (img.onload = () => resolve(img)));
} }
<div class="wizard-container__preview">
<canvas
width={{this.elementWidth}}
height={{this.elementHeight}}
style={{this.canvasStyle}}
>
</canvas>
</div>

View File

@ -1,3 +1,4 @@
import { on } from "@ember/modifier";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { observes } from "@ember-decorators/object"; import { observes } from "@ember-decorators/object";
import { bind } from "discourse/lib/decorators"; import { bind } from "discourse/lib/decorators";
@ -247,8 +248,8 @@ export default class Index extends PreviewBaseComponent {
event?.preventDefault(); event?.preventDefault();
this.set("previewTopic", true); this.set("previewTopic", true);
} }
}
<template>
<div class="previews {{if this.draggingActive 'dragging'}}"> <div class="previews {{if this.draggingActive 'dragging'}}">
<div class="wizard-container__preview topic-preview"> <div class="wizard-container__preview topic-preview">
<canvas <canvas
@ -279,3 +280,5 @@ export default class Index extends PreviewBaseComponent {
{{i18n "wizard.previews.homepage_preview"}} {{i18n "wizard.previews.homepage_preview"}}
</a> </a>
</div> </div>
</template>
}

View File

@ -1,7 +1,7 @@
import Component from "@ember/component"; import Component, { Input } from "@ember/component";
export default class Text extends Component {}
export default class Text extends Component {
<template>
<Input <Input
id={{this.field.id}} id={{this.field.id}}
@value={{this.field.value}} @value={{this.field.value}}
@ -9,3 +9,5 @@ export default class Text extends Component {}
placeholder={{this.field.placeholder}} placeholder={{this.field.placeholder}}
tabindex="9" tabindex="9"
/> />
</template>
}

View File

@ -29,8 +29,8 @@ export default class ColorPalettesRow extends SelectKitRowComponent {
return ""; return "";
} }
} }
}
<template>
<span class="name"> <span class="name">
{{this.label}} {{this.label}}
</span> </span>
@ -40,3 +40,5 @@ export default class ColorPalettesRow extends SelectKitRowComponent {
{{this.palettes}} {{this.palettes}}
</div> </div>
{{/if}} {{/if}}
</template>
}

View File

@ -15,6 +15,8 @@ export default class CreateColorRow extends SelectKitRowComponent {
: `#${color}`; : `#${color}`;
}); });
} }
}
<template>
<span>{{this.label}}</span> <span>{{this.label}}</span>
</template>
}

View File

@ -1,24 +1,28 @@
import { readOnly } from "@ember/object/computed"; import { readOnly } from "@ember/object/computed";
import { htmlSafe } from "@ember/template";
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import icon from "discourse/helpers/d-icon";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@classNames("dropdown-select-box-row") @classNames("dropdown-select-box-row")
export default class DropdownSelectBoxRow extends SelectKitRowComponent { export default class DropdownSelectBoxRow extends SelectKitRowComponent {
@readOnly("item.description") description; @readOnly("item.description") description;
}
<template>
{{#if this.icons}} {{#if this.icons}}
<div class="icons"> <div class="icons">
<span class="selection-indicator"></span> <span class="selection-indicator"></span>
{{#each this.icons as |icon|}} {{#each this.icons as |i|}}
{{d-icon icon}} {{icon i}}
{{/each}} {{/each}}
</div> </div>
{{/if}} {{/if}}
<div class="texts"> <div class="texts">
<span class="name">{{html-safe this.label}}</span> <span class="name">{{htmlSafe this.label}}</span>
{{#if this.description}} {{#if this.description}}
<span class="desc">{{html-safe this.description}}</span> <span class="desc">{{htmlSafe this.description}}</span>
{{/if}} {{/if}}
</div> </div>
</template>
}

View File

@ -1,26 +1,37 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import { and } from "truth-helpers";
import UserStatusMessage from "discourse/components/user-status-message";
import avatar from "discourse/helpers/avatar";
import icon from "discourse/helpers/d-icon";
import decorateUsernameSelector from "discourse/helpers/decorate-username-selector";
import formatUsername from "discourse/helpers/format-username";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@classNames("email-group-user-chooser-row") @classNames("email-group-user-chooser-row")
export default class EmailGroupUserChooserRow extends SelectKitRowComponent {} export default class EmailGroupUserChooserRow extends SelectKitRowComponent {
<template>
{{#if this.item.isUser}} {{#if this.item.isUser}}
{{avatar this.item imageSize="tiny"}} {{avatar this.item imageSize="tiny"}}
<div> <div>
<span class="identifier">{{format-username this.item.id}}</span> <span class="identifier">{{formatUsername this.item.id}}</span>
<span class="name">{{this.item.name}}</span> <span class="name">{{this.item.name}}</span>
</div> </div>
{{#if (and this.item.showUserStatus this.item.status)}} {{#if (and this.item.showUserStatus this.item.status)}}
<UserStatusMessage @status={{this.item.status}} @showDescription={{true}} /> <UserStatusMessage
@status={{this.item.status}}
@showDescription={{true}}
/>
{{/if}} {{/if}}
{{decorate-username-selector this.item.id}} {{decorateUsernameSelector this.item.id}}
{{else if this.item.isGroup}} {{else if this.item.isGroup}}
{{d-icon "users"}} {{icon "users"}}
<div> <div>
<span class="identifier">{{this.item.id}}</span> <span class="identifier">{{this.item.id}}</span>
<span class="name">{{this.item.full_name}}</span> <span class="name">{{this.item.full_name}}</span>
</div> </div>
{{else}} {{else}}
{{d-icon "envelope"}} {{icon "envelope"}}
<span class="identifier">{{this.item.id}}</span> <span class="identifier">{{this.item.id}}</span>
{{/if}} {{/if}}
</template>
}

View File

@ -1,9 +1,10 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import AvatarFlair from "discourse/components/avatar-flair";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@classNames("flair-row") @classNames("flair-row")
export default class FlairRow extends SelectKitRowComponent {} export default class FlairRow extends SelectKitRowComponent {
<template>
{{#if this.item.url}} {{#if this.item.url}}
<AvatarFlair <AvatarFlair
@flairName={{this.item.name}} @flairName={{this.item.name}}
@ -14,3 +15,5 @@ export default class FlairRow extends SelectKitRowComponent {}
{{/if}} {{/if}}
<span>{{this.label}}</span> <span>{{this.label}}</span>
</template>
}

View File

@ -1,12 +1,13 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import icon from "discourse/helpers/d-icon";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@classNames("future-date-input-selector-row") @classNames("future-date-input-selector-row")
export default class FutureDateInputSelectorRow extends SelectKitRowComponent {} export default class FutureDateInputSelectorRow extends SelectKitRowComponent {
<template>
{{#if this.item.icon}} {{#if this.item.icon}}
<div class="future-date-input-selector-icons"> <div class="future-date-input-selector-icons">
{{d-icon this.item.icon}} {{icon this.item.icon}}
</div> </div>
{{/if}} {{/if}}
@ -17,3 +18,5 @@ export default class FutureDateInputSelectorRow extends SelectKitRowComponent {}
{{this.item.timeFormatted}} {{this.item.timeFormatted}}
</span> </span>
{{/if}} {{/if}}
</template>
}

View File

@ -1,12 +1,15 @@
import { htmlSafe } from "@ember/template";
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@classNames("homepage-style-selector-row") @classNames("homepage-style-selector-row")
export default class HomepageStyleSelectorRow extends SelectKitRowComponent {} export default class HomepageStyleSelectorRow extends SelectKitRowComponent {
<template>
<div class="texts"> <div class="texts">
<span class="name">{{html-safe this.label}}</span> <span class="name">{{htmlSafe this.label}}</span>
{{#if this.item.description}} {{#if this.item.description}}
<span class="desc">{{html-safe this.item.description}}</span> <span class="desc">{{htmlSafe this.item.description}}</span>
{{/if}} {{/if}}
</div> </div>
</template>
}

View File

@ -1,7 +1,10 @@
import Component from "@ember/component"; import Component from "@ember/component";
import { fn } from "@ember/helper";
import { computed } from "@ember/object"; import { computed } from "@ember/object";
import { reads } from "@ember/object/computed"; import { reads } from "@ember/object/computed";
import { tagName } from "@ember-decorators/component"; import { tagName } from "@ember-decorators/component";
import DButton from "discourse/components/d-button";
import discourseTag from "discourse/helpers/discourse-tag";
@tagName("") @tagName("")
export default class SelectedCollection extends Component { export default class SelectedCollection extends Component {
@ -27,8 +30,8 @@ export default class SelectedCollection extends Component {
}; };
}); });
} }
}
<template>
{{#if this.tags}} {{#if this.tags}}
<div class="mini-tag-chooser-selected-collection selected-tags"> <div class="mini-tag-chooser-selected-collection selected-tags">
{{#each this.tags as |tag|}} {{#each this.tags as |tag|}}
@ -39,8 +42,10 @@ export default class SelectedCollection extends Component {
tabindex="0" tabindex="0"
class={{tag.classNames}} class={{tag.classNames}}
> >
{{discourse-tag tag.value noHref=true}} {{discourseTag tag.value noHref=true}}
</DButton> </DButton>
{{/each}} {{/each}}
</div> </div>
{{/if}} {{/if}}
</template>
}

View File

@ -21,8 +21,10 @@ export default class FormatSelectedContent extends Component.extend(
return this.getName(this.selectKit.noneItem); return this.getName(this.selectKit.noneItem);
} }
} }
}
<template>
<span class="formatted-selection"> <span class="formatted-selection">
{{this.formattedContent}} {{this.formattedContent}}
</span> </span>
</template>
}

View File

@ -1,6 +1,9 @@
import { Input } from "@ember/component";
import { on } from "@ember/modifier";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { isEmpty } from "@ember/utils"; import { isEmpty } from "@ember/utils";
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import icon from "discourse/helpers/d-icon";
import discourseComputed from "discourse/lib/decorators"; import discourseComputed from "discourse/lib/decorators";
import SelectKitFilterComponent from "select-kit/components/select-kit/select-kit-filter"; import SelectKitFilterComponent from "select-kit/components/select-kit/select-kit-filter";
@ -34,8 +37,8 @@ export default class MultiSelectFilter extends SelectKitFilterComponent {
return false; return false;
} }
} }
}
<template>
{{#unless this.isHidden}} {{#unless this.isHidden}}
{{! filter-input-search prevents 1password from attempting autocomplete }} {{! filter-input-search prevents 1password from attempting autocomplete }}
{{! template-lint-disable no-pointer-down-event-binding }} {{! template-lint-disable no-pointer-down-event-binding }}
@ -58,6 +61,8 @@ export default class MultiSelectFilter extends SelectKitFilterComponent {
/> />
{{#if this.selectKit.options.filterIcon}} {{#if this.selectKit.options.filterIcon}}
{{d-icon this.selectKit.options.filterIcon class="filter-icon"}} {{icon this.selectKit.options.filterIcon class="filter-icon"}}
{{/if}} {{/if}}
{{/unless}} {{/unless}}
</template>
}

View File

@ -1,7 +1,9 @@
import { on } from "@ember/modifier";
import { computed } from "@ember/object"; import { computed } from "@ember/object";
import { htmlSafe } from "@ember/template"; import { htmlSafe } from "@ember/template";
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import { categoryBadgeHTML } from "discourse/helpers/category-link"; import { categoryBadgeHTML } from "discourse/helpers/category-link";
import icon from "discourse/helpers/d-icon";
import SelectedNameComponent from "select-kit/components/selected-name"; import SelectedNameComponent from "select-kit/components/selected-name";
@classNames("selected-category") @classNames("selected-category")
@ -15,8 +17,8 @@ export default class SelectedCategory extends SelectedNameComponent {
}) })
); );
} }
}
<template>
<div <div
{{on "click" this.onSelectedNameClick}} {{on "click" this.onSelectedNameClick}}
tabindex="0" tabindex="0"
@ -27,6 +29,8 @@ export default class SelectedCategory extends SelectedNameComponent {
> >
<div class="body"> <div class="body">
{{this.badge}} {{this.badge}}
{{d-icon "xmark"}} {{icon "xmark"}}
</div> </div>
</div> </div>
</template>
}

View File

@ -1,6 +1,7 @@
import { htmlSafe } from "@ember/template"; import { htmlSafe } from "@ember/template";
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import { categoryBadgeHTML } from "discourse/helpers/category-link"; import { categoryBadgeHTML } from "discourse/helpers/category-link";
import dirSpan from "discourse/helpers/dir-span";
import discourseComputed from "discourse/lib/decorators"; import discourseComputed from "discourse/lib/decorators";
import CategoryRowComponent from "select-kit/components/category-row"; import CategoryRowComponent from "select-kit/components/category-row";
@ -16,8 +17,8 @@ export default class NoneCategoryRow extends CategoryRowComponent {
}) })
); );
} }
}
<template>
{{#if this.category}} {{#if this.category}}
<div class="category-status" aria-hidden="true"> <div class="category-status" aria-hidden="true">
{{#if this.hasParentCategory}} {{#if this.hasParentCategory}}
@ -29,11 +30,13 @@ export default class NoneCategoryRow extends CategoryRowComponent {
</div> </div>
{{#if this.shouldDisplayDescription}} {{#if this.shouldDisplayDescription}}
<div class="category-desc" aria-hidden="true">{{dir-span <div class="category-desc" aria-hidden="true">{{dirSpan
this.descriptionText this.descriptionText
htmlSafe="true" htmlSafe="true"
}}</div> }}</div>
{{/if}} {{/if}}
{{else}} {{else}}
{{html-safe this.label}} {{htmlSafe this.label}}
{{/if}} {{/if}}
</template>
}

View File

@ -1,6 +1,8 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import icon from "discourse/helpers/d-icon";
import { fmt } from "discourse/lib/computed"; import { fmt } from "discourse/lib/computed";
import discourseComputed from "discourse/lib/decorators"; import discourseComputed from "discourse/lib/decorators";
import { i18n } from "discourse-i18n";
import DropdownSelectBoxHeaderComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-header"; import DropdownSelectBoxHeaderComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-header";
@classNames("notifications-filter-header", "btn-flat") @classNames("notifications-filter-header", "btn-flat")
@ -11,8 +13,8 @@ export default class NotificationsFilterHeader extends DropdownSelectBoxHeaderCo
caretIcon(isExpanded) { caretIcon(isExpanded) {
return isExpanded ? "caret-up" : "caret-down"; return isExpanded ? "caret-up" : "caret-down";
} }
}
<template>
<div class="select-kit-header-wrapper"> <div class="select-kit-header-wrapper">
<span class="filter-text"> <span class="filter-text">
{{i18n "user.user_notifications.filters.filter_by"}} {{i18n "user.user_notifications.filters.filter_by"}}
@ -20,5 +22,7 @@ export default class NotificationsFilterHeader extends DropdownSelectBoxHeaderCo
<span class="header-text"> <span class="header-text">
{{i18n this.label}} {{i18n this.label}}
</span> </span>
{{d-icon this.caretIcon class="caret-icon"}} {{icon this.caretIcon class="caret-icon"}}
</div> </div>
</template>
}

View File

@ -1,4 +1,6 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import icon from "discourse/helpers/d-icon";
import periodTitle from "discourse/helpers/period-title";
import discourseComputed from "discourse/lib/decorators"; import discourseComputed from "discourse/lib/decorators";
import DropdownSelectBoxHeaderComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-header"; import DropdownSelectBoxHeaderComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-header";
@ -8,14 +10,16 @@ export default class PeriodChooserHeader extends DropdownSelectBoxHeaderComponen
caretIcon(isExpanded) { caretIcon(isExpanded) {
return isExpanded ? "caret-up" : "caret-down"; return isExpanded ? "caret-up" : "caret-down";
} }
}
<template>
<h2 class="selected-name" title={{this.title}}> <h2 class="selected-name" title={{this.title}}>
{{period-title {{periodTitle
this.value this.value
showDateRange=true showDateRange=true
fullDay=this.selectKit.options.fullDay fullDay=this.selectKit.options.fullDay
}} }}
</h2> </h2>
{{d-icon this.caretIcon class="caret-icon"}} {{icon this.caretIcon class="caret-icon"}}
</template>
}

View File

@ -1,4 +1,5 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import periodTitle from "discourse/helpers/period-title";
import discourseComputed from "discourse/lib/decorators"; import discourseComputed from "discourse/lib/decorators";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import DropdownSelectBoxRowComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-row"; import DropdownSelectBoxRowComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-row";
@ -9,14 +10,16 @@ export default class PeriodChooserRow extends DropdownSelectBoxRowComponent {
title(rowName) { title(rowName) {
return i18n(`filters.top.${rowName || "this_week"}`).title; return i18n(`filters.top.${rowName || "this_week"}`).title;
} }
}
<template>
<span class="selection-indicator"></span> <span class="selection-indicator"></span>
<span class="period-title"> <span class="period-title">
{{period-title {{periodTitle
this.rowValue this.rowValue
showDateRange=true showDateRange=true
fullDay=this.selectKit.options.fullDay fullDay=this.selectKit.options.fullDay
}} }}
</span> </span>
</template>
}

View File

@ -2,8 +2,8 @@ import Component from "@ember/component";
import { tagName } from "@ember-decorators/component"; import { tagName } from "@ember-decorators/component";
@tagName("") @tagName("")
export default class ErrorsCollection extends Component {} export default class ErrorsCollection extends Component {
<template>
{{#if this.collection.content}} {{#if this.collection.content}}
<ul class="select-kit-errors-collection"> <ul class="select-kit-errors-collection">
{{#each this.collection.content as |item|}} {{#each this.collection.content as |item|}}
@ -11,3 +11,5 @@ export default class ErrorsCollection extends Component {}
{{/each}} {{/each}}
</ul> </ul>
{{/if}} {{/if}}
</template>
}

View File

@ -61,8 +61,10 @@ export default class SelectKitBody extends Component {
this.selectKit.close(event); this.selectKit.close(event);
}); });
} }
}
<template>
{{#if this.selectKit.isExpanded}} {{#if this.selectKit.isExpanded}}
{{yield}} {{yield}}
{{/if}} {{/if}}
</template>
}

View File

@ -1,13 +1,16 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import icon from "discourse/helpers/d-icon";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@classNames("create") @classNames("create")
export default class SelectKitCreateRow extends SelectKitRowComponent {} export default class SelectKitCreateRow extends SelectKitRowComponent {
<template>
{{#each this.icons as |icon|}} {{#each this.icons as |i|}}
{{d-icon icon translatedTitle=this.dasherizedTitle}} {{icon i translatedTitle=this.dasherizedTitle}}
{{/each}} {{/each}}
<span class="name"> <span class="name">
{{this.label}} {{this.label}}
</span> </span>
</template>
}

View File

@ -1,4 +1,5 @@
import Component from "@ember/component"; import Component, { Input } from "@ember/component";
import { on } from "@ember/modifier";
import { action, computed } from "@ember/object"; import { action, computed } from "@ember/object";
import { not } from "@ember/object/computed"; import { not } from "@ember/object/computed";
import { isPresent } from "@ember/utils"; import { isPresent } from "@ember/utils";
@ -7,6 +8,7 @@ import {
classNameBindings, classNameBindings,
classNames, classNames,
} from "@ember-decorators/component"; } from "@ember-decorators/component";
import icon from "discourse/helpers/d-icon";
import discourseComputed from "discourse/lib/decorators"; import discourseComputed from "discourse/lib/decorators";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import UtilsMixin from "select-kit/mixins/utils"; import UtilsMixin from "select-kit/mixins/utils";
@ -137,8 +139,8 @@ export default class SelectKitFilter extends Component.extend(UtilsMixin) {
this.selectKit.set("highlighted", null); this.selectKit.set("highlighted", null);
} }
}
<template>
{{#unless this.isHidden}} {{#unless this.isHidden}}
{{! filter-input-search prevents 1password from attempting autocomplete }} {{! filter-input-search prevents 1password from attempting autocomplete }}
{{! template-lint-disable no-pointer-down-event-binding }} {{! template-lint-disable no-pointer-down-event-binding }}
@ -161,6 +163,8 @@ export default class SelectKitFilter extends Component.extend(UtilsMixin) {
/> />
{{#if this.selectKit.options.filterIcon}} {{#if this.selectKit.options.filterIcon}}
{{d-icon this.selectKit.options.filterIcon class="filter-icon"}} {{icon this.selectKit.options.filterIcon class="filter-icon"}}
{{/if}} {{/if}}
{{/unless}} {{/unless}}
</template>
}

View File

@ -1,13 +1,16 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import icon from "discourse/helpers/d-icon";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@classNames("none") @classNames("none")
export default class SelectKitNoneRow extends SelectKitRowComponent {} export default class SelectKitNoneRow extends SelectKitRowComponent {
<template>
{{#each this.icons as |icon|}} {{#each this.icons as |i|}}
{{d-icon icon translatedTitle=this.dasherizedTitle}} {{icon i translatedTitle=this.dasherizedTitle}}
{{/each}} {{/each}}
<span class="name"> <span class="name">
{{this.label}} {{this.label}}
</span> </span>
</template>
}

View File

@ -9,6 +9,7 @@ import {
classNames, classNames,
tagName, tagName,
} from "@ember-decorators/component"; } from "@ember-decorators/component";
import icon from "discourse/helpers/d-icon";
import { makeArray } from "discourse/lib/helpers"; import { makeArray } from "discourse/lib/helpers";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import UtilsMixin from "select-kit/mixins/utils"; import UtilsMixin from "select-kit/mixins/utils";
@ -117,9 +118,9 @@ export default class SelectKitRow extends Component.extend(UtilsMixin) {
@computed("item.{icon,icons}") @computed("item.{icon,icons}")
get icons() { get icons() {
const icon = makeArray(this.getProperty(this.item, "icon")); const _icon = makeArray(this.getProperty(this.item, "icon"));
const icons = makeArray(this.getProperty(this.item, "icons")); const icons = makeArray(this.getProperty(this.item, "icons"));
return icon.concat(icons).filter(Boolean); return _icon.concat(icons).filter(Boolean);
} }
@computed("selectKit.highlighted") @computed("selectKit.highlighted")
@ -203,12 +204,14 @@ export default class SelectKitRow extends Component.extend(UtilsMixin) {
} }
} }
} }
}
{{#each this.icons as |icon|}} <template>
{{d-icon icon translatedTitle=this.dasherizedTitle}} {{#each this.icons as |i|}}
{{icon i translatedTitle=this.dasherizedTitle}}
{{/each}} {{/each}}
<span class="name"> <span class="name">
{{this.label}} {{this.label}}
</span> </span>
</template>
}

View File

@ -1,7 +1,11 @@
import Component from "@ember/component"; import Component from "@ember/component";
import { fn } from "@ember/helper";
import { on } from "@ember/modifier";
import { computed } from "@ember/object"; import { computed } from "@ember/object";
import { guidFor } from "@ember/object/internals"; import { guidFor } from "@ember/object/internals";
import { tagName } from "@ember-decorators/component"; import { tagName } from "@ember-decorators/component";
import icon from "discourse/helpers/d-icon";
import { i18n } from "discourse-i18n";
import UtilsMixin from "select-kit/mixins/utils"; import UtilsMixin from "select-kit/mixins/utils";
@tagName("") @tagName("")
@ -39,12 +43,12 @@ export default class SelectedChoice extends Component.extend(UtilsMixin) {
} }
return this.mandatoryValuesArray.includes(this.item.id); return this.mandatoryValuesArray.includes(this.item.id);
} }
}
<template>
{{#if this.readOnly}} {{#if this.readOnly}}
<button <button
class="btn btn-default disabled" class="btn btn-default disabled"
title={{I18n "admin.site_settings.mandatory_group"}} title={{i18n "admin.site_settings.mandatory_group"}}
>{{this.itemName}}</button> >{{this.itemName}}</button>
{{else}} {{else}}
<button <button
@ -56,7 +60,7 @@ export default class SelectedChoice extends Component.extend(UtilsMixin) {
id="{{this.id}}-choice" id="{{this.id}}-choice"
class="btn btn-default selected-choice {{this.extraClass}}" class="btn btn-default selected-choice {{this.extraClass}}"
> >
{{d-icon "xmark"}} {{icon "xmark"}}
{{#if (has-block)}} {{#if (has-block)}}
{{yield}} {{yield}}
{{else}} {{else}}
@ -66,3 +70,5 @@ export default class SelectedChoice extends Component.extend(UtilsMixin) {
{{/if}} {{/if}}
</button> </button>
{{/if}} {{/if}}
</template>
}

View File

@ -1,9 +1,10 @@
import { tagName } from "@ember-decorators/component"; import { tagName } from "@ember-decorators/component";
import AvatarFlair from "discourse/components/avatar-flair";
import SelectedNameComponent from "select-kit/components/selected-name"; import SelectedNameComponent from "select-kit/components/selected-name";
@tagName("") @tagName("")
export default class SelectedFlair extends SelectedNameComponent {} export default class SelectedFlair extends SelectedNameComponent {
<template>
{{#if this.item.url}} {{#if this.item.url}}
<AvatarFlair <AvatarFlair
@flairName={{this.item.name}} @flairName={{this.item.name}}
@ -14,3 +15,5 @@ export default class SelectedFlair extends SelectedNameComponent {}
{{/if}} {{/if}}
<span>{{this.label}}</span> <span>{{this.label}}</span>
</template>
}

View File

@ -1,8 +1,12 @@
import Component from "@ember/component"; import Component from "@ember/component";
import { fn } from "@ember/helper";
import { computed, get } from "@ember/object"; import { computed, get } from "@ember/object";
import { reads } from "@ember/object/computed"; import { reads } from "@ember/object/computed";
import { guidFor } from "@ember/object/internals"; import { guidFor } from "@ember/object/internals";
import { tagName } from "@ember-decorators/component"; import { tagName } from "@ember-decorators/component";
import { and } from "truth-helpers";
import DButton from "discourse/components/d-button";
import icon from "discourse/helpers/d-icon";
import { makeArray } from "discourse/lib/helpers"; import { makeArray } from "discourse/lib/helpers";
import UtilsMixin from "select-kit/mixins/utils"; import UtilsMixin from "select-kit/mixins/utils";
@ -77,9 +81,9 @@ export default class SelectedName extends Component.extend(UtilsMixin) {
@computed("item.{icon,icons}") @computed("item.{icon,icons}")
get icons() { get icons() {
const icon = makeArray(this._safeProperty("icon", this.item)); const _icon = makeArray(this._safeProperty("icon", this.item));
const icons = makeArray(this._safeProperty("icons", this.item)); const icons = makeArray(this._safeProperty("icons", this.item));
return icon.concat(icons).filter(Boolean); return _icon.concat(icons).filter(Boolean);
} }
_safeProperty(name, content) { _safeProperty(name, content) {
@ -89,8 +93,8 @@ export default class SelectedName extends Component.extend(UtilsMixin) {
return get(content, name); return get(content, name);
} }
}
<template>
{{#if this.selectKit.options.showFullTitle}} {{#if this.selectKit.options.showFullTitle}}
<div <div
lang={{this.lang}} lang={{this.lang}}
@ -108,7 +112,7 @@ export default class SelectedName extends Component.extend(UtilsMixin) {
{{/if}} {{/if}}
{{#if (and this.renderIcon this.item.icon)}} {{#if (and this.renderIcon this.item.icon)}}
{{d-icon this.item.icon}} {{icon this.item.icon}}
{{/if}} {{/if}}
<span class="name"> <span class="name">
@ -130,7 +134,9 @@ export default class SelectedName extends Component.extend(UtilsMixin) {
lang={{this.lang}} lang={{this.lang}}
class="select-kit-selected-name selected-name choice" class="select-kit-selected-name selected-name choice"
> >
{{d-icon this.item.icon}} {{icon this.item.icon}}
</div> </div>
{{/if}} {{/if}}
{{/if}} {{/if}}
</template>
}

View File

@ -1,7 +1,10 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import discourseTag from "discourse/helpers/discourse-tag";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@classNames("tag-chooser-row") @classNames("tag-chooser-row")
export default class TagChooserRow extends SelectKitRowComponent {} export default class TagChooserRow extends SelectKitRowComponent {
<template>
{{discourse-tag this.rowValue count=this.item.count noHref=true}} {{discourseTag this.rowValue count=this.item.count noHref=true}}
</template>
}

View File

@ -1,4 +1,5 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import discourseTag from "discourse/helpers/discourse-tag";
import discourseComputed from "discourse/lib/decorators"; import discourseComputed from "discourse/lib/decorators";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@ -8,10 +9,10 @@ export default class TagRow extends SelectKitRowComponent {
isTag(item) { isTag(item) {
return item.id !== "no-tags" && item.id !== "all-tags"; return item.id !== "no-tags" && item.id !== "all-tags";
} }
}
<template>
{{#if this.isTag}} {{#if this.isTag}}
{{discourse-tag {{discourseTag
this.rowValue this.rowValue
noHref=true noHref=true
description=this.item.description description=this.item.description
@ -20,3 +21,5 @@ export default class TagRow extends SelectKitRowComponent {
{{else}} {{else}}
<span class="name">{{this.item.name}}</span> <span class="name">{{this.item.name}}</span>
{{/if}} {{/if}}
</template>
}

View File

@ -1,5 +1,5 @@
import Component from "@ember/component"; import Component from "@ember/component";
export default class ToolbarPopupMenuOptionsHeading extends Component {} export default class ToolbarPopupMenuOptionsHeading extends Component {
<template>{{this.heading}}</template>
{{this.heading}} }

View File

@ -1,16 +1,21 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import TopicStatus from "discourse/components/topic-status";
import boundCategoryLink from "discourse/helpers/bound-category-link";
import replaceEmoji from "discourse/helpers/replace-emoji";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@classNames("topic-row") @classNames("topic-row")
export default class TopicRow extends SelectKitRowComponent {} export default class TopicRow extends SelectKitRowComponent {
<template>
<TopicStatus @topic={{this.item}} @disableActions={{true}} /> <TopicStatus @topic={{this.item}} @disableActions={{true}} />
<div class="topic-title">{{replace-emoji this.item.title}}</div> <div class="topic-title">{{replaceEmoji this.item.title}}</div>
<div class="topic-categories"> <div class="topic-categories">
{{bound-category-link {{boundCategoryLink
this.item.category this.item.category
ancestors=this.item.category.predecessors ancestors=this.item.category.predecessors
hideParent=true hideParent=true
link=false link=false
}} }}
</div> </div>
</template>
}

View File

@ -1,13 +1,17 @@
import { classNames } from "@ember-decorators/component"; import { classNames } from "@ember-decorators/component";
import avatar from "discourse/helpers/avatar";
import formatUsername from "discourse/helpers/format-username";
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
@classNames("user-row") @classNames("user-row")
export default class UserRow extends SelectKitRowComponent {} export default class UserRow extends SelectKitRowComponent {
<template>
{{avatar this.item imageSize="tiny"}} {{avatar this.item imageSize="tiny"}}
<span class="username">{{format-username this.item.username}}</span> <span class="username">{{formatUsername this.item.username}}</span>
{{#if this.item.name}} {{#if this.item.name}}
<span class="name">{{this.item.name}}</span> <span class="name">{{this.item.name}}</span>
{{/if}} {{/if}}
</template>
}

View File

@ -20,7 +20,8 @@
"ember-auto-import": "^2.10.0", "ember-auto-import": "^2.10.0",
"ember-cli-babel": "^8.2.0", "ember-cli-babel": "^8.2.0",
"ember-cli-htmlbars": "^6.3.0", "ember-cli-htmlbars": "^6.3.0",
"ember-template-imports": "^4.3.0" "ember-template-imports": "^4.3.0",
"truth-helpers": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"@ember/optional-features": "^2.2.0", "@ember/optional-features": "^2.2.0",

View File

@ -3,7 +3,7 @@ import I18n, { i18n } from "discourse-i18n";
import DaBooleanField from "./fields/da-boolean-field"; import DaBooleanField from "./fields/da-boolean-field";
import DaCategoriesField from "./fields/da-categories-field"; import DaCategoriesField from "./fields/da-categories-field";
import DaCategoryField from "./fields/da-category-field"; import DaCategoryField from "./fields/da-category-field";
import DaCategoryNotificationlevelField from "./fields/da-category-notification-level-field"; import DaCategoryNotificationLevelField from "./fields/da-category-notification-level-field";
import DaChoicesField from "./fields/da-choices-field"; import DaChoicesField from "./fields/da-choices-field";
import DaCustomField from "./fields/da-custom-field"; import DaCustomField from "./fields/da-custom-field";
import DaCustomFields from "./fields/da-custom-fields"; import DaCustomFields from "./fields/da-custom-fields";
@ -44,7 +44,7 @@ const FIELD_COMPONENTS = {
group: DaGroupField, group: DaGroupField,
groups: DaGroupsField, groups: DaGroupsField,
choices: DaChoicesField, choices: DaChoicesField,
category_notification_level: DaCategoryNotificationlevelField, category_notification_level: DaCategoryNotificationLevelField,
email_group_user: DaEmailGroupUserField, email_group_user: DaEmailGroupUserField,
custom_field: DaCustomField, custom_field: DaCustomField,
custom_fields: DaCustomFields, custom_fields: DaCustomFields,

View File

@ -3,7 +3,7 @@ import BaseField from "./da-base-field";
import DAFieldDescription from "./da-field-description"; import DAFieldDescription from "./da-field-description";
import DAFieldLabel from "./da-field-label"; import DAFieldLabel from "./da-field-label";
export default class CategoryNotficationLevelField extends BaseField { export default class CategoryNotificationLevelField extends BaseField {
<template> <template>
<section class="field category-notification-level-field"> <section class="field category-notification-level-field">
<div class="control-group"> <div class="control-group">

View File

@ -0,0 +1,10 @@
import htmlSafe from "discourse/helpers/html-safe";
const FormError = <template>
{{#if @error}}
<div class="alert alert-error form-errors">
{{htmlSafe @error}}
</div>
{{/if}}
</template>;
export default FormError;

View File

@ -0,0 +1,22 @@
import { Input } from "@ember/component";
import { on } from "@ember/modifier";
import { i18n } from "discourse-i18n";
const TopicTrigger = <template>
<div class="control-group">
<label class="control-label">
{{i18n "discourse_automation.triggerables.topic.topic_id.label"}}
</label>
<div class="controls">
<Input
@value={{this.metadata.topic_id}}
{{on
"input"
(action (mut this.metadata.topic_id) value="target.value")
}}
/>
</div>
</div>
</template>;
export default TopicTrigger;

View File

@ -1,5 +0,0 @@
{{#if @error}}
<div class="alert alert-error form-errors">
{{html-safe @error}}
</div>
{{/if}}

View File

@ -1,12 +0,0 @@
<div class="control-group">
<label class="control-label">
{{i18n "discourse_automation.triggerables.topic.topic_id.label"}}
</label>
<div class="controls">
<Input
@value={{this.metadata.topic_id}}
{{on "input" (action (mut this.metadata.topic_id) value="target.value")}}
/>
</div>
</div>

View File

@ -1,4 +1,23 @@
<div class="admin-detail discourse-automation-edit discourse-automation-form"> import { Input } from "@ember/component";
import { fn, hash } from "@ember/helper";
import { on } from "@ember/modifier";
import RouteTemplate from "ember-route-template";
import { and } from "truth-helpers";
import BackButton from "discourse/components/back-button";
import DButton from "discourse/components/d-button";
import TextField from "discourse/components/text-field";
import withEventValue from "discourse/helpers/with-event-value";
import { i18n } from "discourse-i18n";
import AdminConfigAreaCard from "admin/components/admin-config-area-card";
import ComboBox from "select-kit/components/combo-box";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import FormError from "discourse/plugins/automation/admin/components/form-error";
export default RouteTemplate(
<template>
<div
class="admin-detail discourse-automation-edit discourse-automation-form"
>
<BackButton <BackButton
@label="discourse_automation.back" @label="discourse_automation.back"
@route="adminPlugins.show.automation.index" @route="adminPlugins.show.automation.index"
@ -7,7 +26,7 @@
<AdminConfigAreaCard @heading="discourse_automation.select_script"> <AdminConfigAreaCard @heading="discourse_automation.select_script">
<:content> <:content>
<form class="form-horizontal"> <form class="form-horizontal">
<FormError @error={{this.error}} /> <FormError @error={{@controller.error}} />
<section class="form-section edit"> <section class="form-section edit">
<div class="control-group"> <div class="control-group">
@ -17,12 +36,14 @@
<div class="controls"> <div class="controls">
<TextField <TextField
@value={{this.automationForm.name}} @value={{@controller.automationForm.name}}
@type="text" @type="text"
@autofocus={{true}} @autofocus={{true}}
@name="automation-name" @name="automation-name"
class="input-large" class="input-large"
@input={{with-event-value (fn (mut this.automationForm.name))}} @input={{withEventValue
(fn (mut @controller.automationForm.name))
}}
/> />
</div> </div>
</div> </div>
@ -34,9 +55,9 @@
<div class="controls"> <div class="controls">
<ComboBox <ComboBox
@value={{this.automationForm.script}} @value={{@controller.automationForm.script}}
@content={{this.model.scriptables}} @content={{@controller.model.scriptables}}
@onChange={{this.onChangeScript}} @onChange={{@controller.onChangeScript}}
@options={{hash filterable=true}} @options={{hash filterable=true}}
class="scriptables" class="scriptables"
/> />
@ -52,7 +73,7 @@
</h2> </h2>
<div class="control-group"> <div class="control-group">
{{#if this.model.automation.script.forced_triggerable}} {{#if @controller.model.automation.script.forced_triggerable}}
<div class="alert alert-warning"> <div class="alert alert-warning">
{{i18n {{i18n
"discourse_automation.edit_automation.trigger_section.forced" "discourse_automation.edit_automation.trigger_section.forced"
@ -66,67 +87,70 @@
<div class="controls"> <div class="controls">
<ComboBox <ComboBox
@value={{this.automationForm.trigger}} @value={{@controller.automationForm.trigger}}
@content={{this.model.triggerables}} @content={{@controller.model.triggerables}}
@onChange={{this.onChangeTrigger}} @onChange={{@controller.onChangeTrigger}}
@options={{hash @options={{hash
filterable=true filterable=true
none="discourse_automation.select_trigger" none="discourse_automation.select_trigger"
disabled=this.model.automation.script.forced_triggerable disabled=@controller.model.automation.script.forced_triggerable
}} }}
class="triggerables" class="triggerables"
/> />
</div> </div>
</div> </div>
{{#if this.automationForm.trigger}} {{#if @controller.automationForm.trigger}}
{{#if this.model.automation.trigger.doc}} {{#if @controller.model.automation.trigger.doc}}
<div class="alert alert-info"> <div class="alert alert-info">
<p>{{this.model.automation.trigger.doc}}</p> <p>{{@controller.model.automation.trigger.doc}}</p>
</div> </div>
{{/if}} {{/if}}
{{#if {{#if
(and (and
this.model.automation.enabled @controller.model.automation.enabled
this.model.automation.trigger.settings.manual_trigger @controller.model.automation.trigger.settings.manual_trigger
) )
}} }}
<div class="alert alert-info next-trigger"> <div class="alert alert-info next-trigger">
{{#if this.nextPendingAutomationAtFormatted}} {{#if @controller.nextPendingAutomationAtFormatted}}
<p> <p>
{{i18n {{i18n
"discourse_automation.edit_automation.trigger_section.next_pending_automation" "discourse_automation.edit_automation.trigger_section.next_pending_automation"
date=this.nextPendingAutomationAtFormatted date=@controller.nextPendingAutomationAtFormatted
}} }}
</p> </p>
{{/if}} {{/if}}
<DButton <DButton
@label="discourse_automation.edit_automation.trigger_section.trigger_now" @label="discourse_automation.edit_automation.trigger_section.trigger_now"
@isLoading={{this.isTriggeringAutomation}} @isLoading={{@controller.isTriggeringAutomation}}
@action={{fn @action={{fn
this.onManualAutomationTrigger @controller.onManualAutomationTrigger
this.model.automation.id @controller.model.automation.id
}} }}
class="btn-primary trigger-now-btn" class="btn-primary trigger-now-btn"
/> />
</div> </div>
{{/if}} {{/if}}
{{#each this.triggerFields as |field|}} {{#each @controller.triggerFields as |field|}}
<AutomationField <AutomationField
@automation={{this.automation}} @automation={{@controller.automation}}
@field={{field}} @field={{field}}
@saveAutomation={{fn this.saveAutomation this.automation}} @saveAutomation={{fn
@controller.saveAutomation
@controller.automation
}}
/> />
{{/each}} {{/each}}
{{/if}} {{/if}}
</section> </section>
{{#if this.automationForm.trigger}} {{#if @controller.automationForm.trigger}}
{{#if this.scriptFields}} {{#if @controller.scriptFields}}
<section class="fields-section form-section edit"> <section class="fields-section form-section edit">
<h2 class="title"> <h2 class="title">
{{i18n {{i18n
@ -134,39 +158,48 @@
}} }}
</h2> </h2>
{{#if this.model.automation.script.with_trigger_doc}} {{#if @controller.model.automation.script.with_trigger_doc}}
<div class="alert alert-info"> <div class="alert alert-info">
<p>{{this.model.automation.script.with_trigger_doc}}</p> <p
>{{@controller.model.automation.script.with_trigger_doc}}</p>
</div> </div>
{{/if}} {{/if}}
<div class="control-group"> <div class="control-group">
{{#each this.scriptFields as |field|}} {{#each @controller.scriptFields as |field|}}
<AutomationField <AutomationField
@automation={{this.automation}} @automation={{@controller.automation}}
@field={{field}} @field={{field}}
@saveAutomation={{fn this.saveAutomation this.automation}} @saveAutomation={{fn
@controller.saveAutomation
@controller.automation
}}
/> />
{{/each}} {{/each}}
</div> </div>
</section> </section>
{{/if}} {{/if}}
{{#if this.automationForm.trigger}} {{#if @controller.automationForm.trigger}}
<div <div
class="control-group automation-enabled alert class="control-group automation-enabled alert
{{if this.automationForm.enabled 'alert-info' 'alert-warning'}}" {{if
@controller.automationForm.enabled
'alert-info'
'alert-warning'
}}"
> >
<span>{{i18n <span>{{i18n
"discourse_automation.models.automation.enabled.label" "discourse_automation.models.automation.enabled.label"
}}</span> }}</span>
<Input <Input
@type="checkbox" @type="checkbox"
@checked={{this.automationForm.enabled}} @checked={{@controller.automationForm.enabled}}
{{on {{on
"click" "click"
(action (action
(mut this.automationForm.enabled) value="target.checked" (mut @controller.automationForm.enabled)
value="target.checked"
) )
}} }}
/> />
@ -175,10 +208,14 @@
<div class="control-group"> <div class="control-group">
<DButton <DButton
@isLoading={{this.isUpdatingAutomation}} @isLoading={{@controller.isUpdatingAutomation}}
@label="discourse_automation.update" @label="discourse_automation.update"
@type="submit" @type="submit"
@action={{fn this.saveAutomation this.automation true}} @action={{fn
@controller.saveAutomation
@controller.automation
true
}}
class="btn-primary update-automation" class="btn-primary update-automation"
/> />
</div> </div>
@ -187,3 +224,5 @@
</:content> </:content>
</AdminConfigAreaCard> </AdminConfigAreaCard>
</div> </div>
</template>
);

View File

@ -1 +1,6 @@
<AutomationList @model={{this.model}} /> import RouteTemplate from "ember-route-template";
import AutomationList from "discourse/plugins/automation/admin/components/automation-list";
export default RouteTemplate(
<template><AutomationList @model={{@controller.model}} /></template>
);

View File

@ -1,4 +1,16 @@
<div class="admin-detail discourse-automation-new discourse-automation-form"> import { fn } from "@ember/helper";
import { on } from "@ember/modifier";
import RouteTemplate from "ember-route-template";
import BackButton from "discourse/components/back-button";
import { i18n } from "discourse-i18n";
import AdminConfigAreaCard from "admin/components/admin-config-area-card";
import AdminSectionLandingItem from "admin/components/admin-section-landing-item";
export default RouteTemplate(
<template>
<div
class="admin-detail discourse-automation-new discourse-automation-form"
>
<BackButton <BackButton
@label="discourse_automation.back" @label="discourse_automation.back"
@route="adminPlugins.show.automation.index" @route="adminPlugins.show.automation.index"
@ -9,14 +21,14 @@
<input <input
type="text" type="text"
placeholder={{i18n "discourse_automation.filter_placeholder"}} placeholder={{i18n "discourse_automation.filter_placeholder"}}
{{on "input" this.updateFilterText}} {{on "input" @controller.updateFilterText}}
class="admin-section-landing__header-filter" class="admin-section-landing__header-filter"
/> />
<div class="admin-section-landing__wrapper"> <div class="admin-section-landing__wrapper">
{{#each this.scriptableContent as |script|}} {{#each @controller.scriptableContent as |script|}}
<AdminSectionLandingItem <AdminSectionLandingItem
{{on "click" (fn this.selectScriptToEdit script)}} {{on "click" (fn @controller.selectScriptToEdit script)}}
@titleLabelTranslated={{script.name}} @titleLabelTranslated={{script.name}}
@descriptionLabelTranslated={{script.description}} @descriptionLabelTranslated={{script.description}}
/> />
@ -25,3 +37,5 @@
</:content> </:content>
</AdminConfigAreaCard> </AdminConfigAreaCard>
</div> </div>
</template>
);

View File

@ -1,8 +1,8 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { click, render } from "@ember/test-helpers"; import { click, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-boolean-field", function (hooks) { module("Integration | Component | da-boolean-field", function (hooks) {
@ -13,10 +13,17 @@ module("Integration | Component | da-boolean-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field(); this.field = new AutomationFabricators(getOwner(this)).field();
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await click("input"); await click("input");

View File

@ -1,9 +1,9 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-categories-field", function (hooks) { module("Integration | Component | da-categories-field", function (hooks) {
@ -14,12 +14,19 @@ module("Integration | Component | da-categories-field", function (hooks) {
}); });
test("sets values", async function (assert) { test("sets values", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "categories", component: "categories",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();

View File

@ -1,9 +1,9 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-category-field", function (hooks) { module("Integration | Component | da-category-field", function (hooks) {
@ -14,12 +14,19 @@ module("Integration | Component | da-category-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "category", component: "category",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();

View File

@ -1,9 +1,9 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import notificationsTracking from "discourse/tests/helpers/notifications-tracking-helper"; import notificationsTracking from "discourse/tests/helpers/notifications-tracking-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module( module(
@ -16,12 +16,19 @@ module(
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "category_notification_level", component: "category_notification_level",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await notificationsTracking().selectLevelId(2); await notificationsTracking().selectLevelId(2);

View File

@ -1,9 +1,9 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-choices-field", function (hooks) { module("Integration | Component | da-choices-field", function (hooks) {
@ -14,13 +14,20 @@ module("Integration | Component | da-choices-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "choices", component: "choices",
extra: { content: [{ name: "One", id: 1 }] }, extra: { content: [{ name: "One", id: 1 }] },
}); });
await render( await render(
hbs` <AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();

View File

@ -1,10 +1,10 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import pretender, { response } from "discourse/tests/helpers/create-pretender"; import pretender, { response } from "discourse/tests/helpers/create-pretender";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-custom-field", function (hooks) { module("Integration | Component | da-custom-field", function (hooks) {
@ -34,12 +34,19 @@ module("Integration | Component | da-custom-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "custom_field", component: "custom_field",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();

View File

@ -1,8 +1,8 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { fillIn, render } from "@ember/test-helpers"; import { fillIn, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-date-time-field", function (hooks) { module("Integration | Component | da-date-time-field", function (hooks) {
@ -13,12 +13,19 @@ module("Integration | Component | da-date-time-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "date_time", component: "date_time",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await fillIn("input", "2023-10-03T12:34"); await fillIn("input", "2023-10-03T12:34");

View File

@ -1,13 +1,15 @@
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import DaEmailGroupUserField from "discourse/plugins/automation/admin/components/fields/da-email-group-user-field";
module("Integration | Component | email-group-user-field", function (hooks) { module("Integration | Component | email-group-user-field", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
test("Email group user field uses email-group-user-chooser component", async function (assert) { test("Email group user field uses email-group-user-chooser component", async function (assert) {
const template = hbs` <Fields::DaEmailGroupUserField @label="a label" />`; const template = <template>
<DaEmailGroupUserField @label="a label" />
</template>;
await render(template); await render(template);

View File

@ -1,10 +1,10 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import pretender, { response } from "discourse/tests/helpers/create-pretender"; import pretender, { response } from "discourse/tests/helpers/create-pretender";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-group-field", function (hooks) { module("Integration | Component | da-group-field", function (hooks) {
@ -27,12 +27,19 @@ module("Integration | Component | da-group-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "group", component: "group",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();

View File

@ -1,10 +1,10 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import pretender, { response } from "discourse/tests/helpers/create-pretender"; import pretender, { response } from "discourse/tests/helpers/create-pretender";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-groups-field", function (hooks) { module("Integration | Component | da-groups-field", function (hooks) {
@ -34,12 +34,19 @@ module("Integration | Component | da-groups-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "groups", component: "groups",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();
@ -49,13 +56,20 @@ module("Integration | Component | da-groups-field", function (hooks) {
}); });
test("supports a maxmimum value", async function (assert) { test("supports a maxmimum value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "groups", component: "groups",
extra: { maximum: 1 }, extra: { maximum: 1 },
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();

View File

@ -1,8 +1,8 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { fillIn, render } from "@ember/test-helpers"; import { fillIn, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-message-field", function (hooks) { module("Integration | Component | da-message-field", function (hooks) {
@ -13,12 +13,19 @@ module("Integration | Component | da-message-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "message", component: "message",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await fillIn("textarea", "Hello World"); await fillIn("textarea", "Hello World");
@ -26,13 +33,20 @@ module("Integration | Component | da-message-field", function (hooks) {
}); });
test("render placeholders", async function (assert) { test("render placeholders", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "message", component: "message",
}); });
this.automation.placeholders = ["foo", "bar"]; this.automation.placeholders = ["foo", "bar"];
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
assert.dom(".placeholders-list").hasText("foo bar"); assert.dom(".placeholders-list").hasText("foo bar");

View File

@ -1,8 +1,8 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { click, fillIn, render } from "@ember/test-helpers"; import { click, fillIn, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-pms-field", function (hooks) { module("Integration | Component | da-pms-field", function (hooks) {
@ -13,12 +13,19 @@ module("Integration | Component | da-pms-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "pms", component: "pms",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await click(".insert-pm"); await click(".insert-pm");

View File

@ -1,8 +1,8 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { fillIn, render } from "@ember/test-helpers"; import { fillIn, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-post-field", function (hooks) { module("Integration | Component | da-post-field", function (hooks) {
@ -13,12 +13,19 @@ module("Integration | Component | da-post-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "post", component: "post",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await fillIn("textarea", "Hello World"); await fillIn("textarea", "Hello World");

View File

@ -1,9 +1,9 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-tags-field", function (hooks) { module("Integration | Component | da-tags-field", function (hooks) {
@ -14,12 +14,19 @@ module("Integration | Component | da-tags-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "tags", component: "tags",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();

View File

@ -1,8 +1,8 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { fillIn, render } from "@ember/test-helpers"; import { fillIn, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-text-field", function (hooks) { module("Integration | Component | da-text-field", function (hooks) {
@ -13,12 +13,19 @@ module("Integration | Component | da-text-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "text", component: "text",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await fillIn("input", "Hello World"); await fillIn("input", "Hello World");

View File

@ -1,9 +1,9 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-text-list-field", function (hooks) { module("Integration | Component | da-text-list-field", function (hooks) {
@ -14,12 +14,19 @@ module("Integration | Component | da-text-list-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "text_list", component: "text_list",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();
await selectKit().fillInFilter("test"); await selectKit().fillInFilter("test");

View File

@ -1,9 +1,9 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-trust-levels-field", function (hooks) { module("Integration | Component | da-trust-levels-field", function (hooks) {
@ -14,12 +14,19 @@ module("Integration | Component | da-trust-levels-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "trust-levels", component: "trust-levels",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();

View File

@ -1,10 +1,10 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import pretender, { response } from "discourse/tests/helpers/create-pretender"; import pretender, { response } from "discourse/tests/helpers/create-pretender";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-user-field", function (hooks) { module("Integration | Component | da-user-field", function (hooks) {
@ -27,12 +27,19 @@ module("Integration | Component | da-user-field", function (hooks) {
}); });
test("set value", async function (assert) { test("set value", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "user", component: "user",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();

View File

@ -1,10 +1,10 @@
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import pretender, { response } from "discourse/tests/helpers/create-pretender"; import pretender, { response } from "discourse/tests/helpers/create-pretender";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import AutomationField from "discourse/plugins/automation/admin/components/automation-field";
import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators"; import AutomationFabricators from "discourse/plugins/automation/admin/lib/fabricators";
module("Integration | Component | da-users-field", function (hooks) { module("Integration | Component | da-users-field", function (hooks) {
@ -32,12 +32,19 @@ module("Integration | Component | da-users-field", function (hooks) {
}); });
test("sets values", async function (assert) { test("sets values", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "users", component: "users",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();
@ -50,12 +57,19 @@ module("Integration | Component | da-users-field", function (hooks) {
}); });
test("allows emails", async function (assert) { test("allows emails", async function (assert) {
const self = this;
this.field = new AutomationFabricators(getOwner(this)).field({ this.field = new AutomationFabricators(getOwner(this)).field({
component: "users", component: "users",
}); });
await render( await render(
hbs`<AutomationField @automation={{this.automation}} @field={{this.field}} />` <template>
<AutomationField
@automation={{self.automation}}
@field={{self.field}}
/>
</template>
); );
await selectKit().expand(); await selectKit().expand();

View File

@ -3,8 +3,24 @@ import { cached } from "@glimmer/tracking";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { optionalRequire } from "discourse/lib/utilities";
import ChatComposerMessageDetails from "discourse/plugins/chat/discourse/components/chat-composer-message-details";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
const StyleguideComponent = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/component"
);
const Controls = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls"
);
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatComposerMessageDetails extends Component { export default class ChatStyleguideChatComposerMessageDetails extends Component {
@service site; @service site;
@service session; @service session;
@ -28,20 +44,22 @@ export default class ChatStyleguideChatComposerMessageDetails extends Component
this.message.inReplyTo = null; this.message.inReplyTo = null;
} }
} }
}
<template>
<StyleguideExample @title="<ChatComposerMessageDetails>"> <StyleguideExample @title="<ChatComposerMessageDetails>">
<Styleguide::Component> <StyleguideComponent>
<ChatComposerMessageDetails @message={{this.message}} /> <ChatComposerMessageDetails @message={{this.message}} />
</Styleguide::Component> </StyleguideComponent>
<Styleguide::Controls> <Controls>
<Styleguide::Controls::Row @name="Mode"> <Row @name="Mode">
{{#if this.message.editing}} {{#if this.message.editing}}
<DButton @action={{this.toggleMode}} @translatedLabel="Reply" /> <DButton @action={{this.toggleMode}} @translatedLabel="Reply" />
{{else}} {{else}}
<DButton @action={{this.toggleMode}} @translatedLabel="Editing" /> <DButton @action={{this.toggleMode}} @translatedLabel="Editing" />
{{/if}} {{/if}}
</Styleguide::Controls::Row> </Row>
</Styleguide::Controls> </Controls>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -1,10 +1,27 @@
import Component from "@glimmer/component"; import Component from "@glimmer/component";
import { on } from "@ember/modifier";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DToggleSwitch from "discourse/components/d-toggle-switch";
import { optionalRequire } from "discourse/lib/utilities";
import Channel from "discourse/plugins/chat/discourse/components/chat/composer/channel";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
import { CHANNEL_STATUSES } from "discourse/plugins/chat/discourse/models/chat-channel"; import { CHANNEL_STATUSES } from "discourse/plugins/chat/discourse/models/chat-channel";
const StyleguideComponent = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/component"
);
const Controls = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls"
);
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatComposer extends Component { export default class ChatStyleguideChatComposer extends Component {
@service chatChannelComposer; @service chatChannelComposer;
@service chatChannelPane; @service chatChannelPane;
@ -29,28 +46,30 @@ export default class ChatStyleguideChatComposer extends Component {
onSendMessage() { onSendMessage() {
this.chatChannelComposer.reset(); this.chatChannelComposer.reset();
} }
}
<template>
<StyleguideExample @title="<ChatComposer>"> <StyleguideExample @title="<ChatComposer>">
<Styleguide::Component> <StyleguideComponent>
<Chat::Composer::Channel <Channel
@channel={{this.channel}} @channel={{this.channel}}
@onSendMessage={{this.onSendMessage}} @onSendMessage={{this.onSendMessage}}
/> />
</Styleguide::Component> </StyleguideComponent>
<Styleguide::Controls> <Controls>
<Styleguide::Controls::Row @name="Disabled"> <Row @name="Disabled">
<DToggleSwitch <DToggleSwitch
@state={{this.channel.isReadOnly}} @state={{this.channel.isReadOnly}}
{{on "click" this.toggleDisabled}} {{on "click" this.toggleDisabled}}
/> />
</Styleguide::Controls::Row> </Row>
<Styleguide::Controls::Row @name="Sending"> <Row @name="Sending">
<DToggleSwitch <DToggleSwitch
@state={{this.chatChannelPane.sending}} @state={{this.chatChannelPane.sending}}
{{on "click" this.toggleSending}} {{on "click" this.toggleSending}}
/> />
</Styleguide::Controls::Row> </Row>
</Styleguide::Controls> </Controls>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -1,6 +1,11 @@
import Component from "@glimmer/component"; import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking"; import { tracked } from "@glimmer/tracking";
import { on } from "@ember/modifier";
import { action } from "@ember/object"; import { action } from "@ember/object";
import DToggleSwitch from "discourse/components/d-toggle-switch";
import { optionalRequire } from "discourse/lib/utilities";
import ComboBox from "select-kit/components/combo-box";
import Icon from "discourse/plugins/chat/discourse/components/chat/header/icon";
import { import {
HEADER_INDICATOR_PREFERENCE_ALL_NEW, HEADER_INDICATOR_PREFERENCE_ALL_NEW,
HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS, HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
@ -8,6 +13,19 @@ import {
HEADER_INDICATOR_PREFERENCE_ONLY_MENTIONS, HEADER_INDICATOR_PREFERENCE_ONLY_MENTIONS,
} from "discourse/plugins/chat/discourse/controllers/preferences-chat"; } from "discourse/plugins/chat/discourse/controllers/preferences-chat";
const StyleguideComponent = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/component"
);
const Controls = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls"
);
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatHeaderIcon extends Component { export default class ChatStyleguideChatHeaderIcon extends Component {
@tracked isActive = false; @tracked isActive = false;
@tracked currentUserInDnD = false; @tracked currentUserInDnD = false;
@ -48,17 +66,17 @@ export default class ChatStyleguideChatHeaderIcon extends Component {
updateIndicatorPreference(value) { updateIndicatorPreference(value) {
this.indicatorPreference = value; this.indicatorPreference = value;
} }
}
<template>
<StyleguideExample @title="<Chat::Header::Icon>"> <StyleguideExample @title="<Chat::Header::Icon>">
<Styleguide::Component> <StyleguideComponent>
<header <header
class="d-header" class="d-header"
style="display: flex; align-items: center; justify-content: center;" style="display: flex; align-items: center; justify-content: center;"
> >
<ul class="d-header-icons"> <ul class="d-header-icons">
<li class="header-dropdown-toggle chat-header-icon"> <li class="header-dropdown-toggle chat-header-icon">
<Chat::Header::Icon <Icon
@isActive={{this.isActive}} @isActive={{this.isActive}}
@currentUserInDnD={{this.currentUserInDnD}} @currentUserInDnD={{this.currentUserInDnD}}
@unreadCount={{this.unreadCount}} @unreadCount={{this.unreadCount}}
@ -68,37 +86,37 @@ export default class ChatStyleguideChatHeaderIcon extends Component {
</li> </li>
</ul> </ul>
</header> </header>
</Styleguide::Component> </StyleguideComponent>
<Styleguide::Controls> <Controls>
<Styleguide::Controls::Row @name="isActive"> <Row @name="isActive">
<DToggleSwitch <DToggleSwitch
@state={{this.isActive}} @state={{this.isActive}}
{{on "click" this.toggleIsActive}} {{on "click" this.toggleIsActive}}
/> />
</Styleguide::Controls::Row> </Row>
<Styleguide::Controls::Row @name="currentUserInDnD"> <Row @name="currentUserInDnD">
<DToggleSwitch <DToggleSwitch
@state={{this.currentUserInDnD}} @state={{this.currentUserInDnD}}
{{on "click" this.toggleCurrentUserInDnD}} {{on "click" this.toggleCurrentUserInDnD}}
/> />
</Styleguide::Controls::Row> </Row>
</Styleguide::Controls> </Controls>
<Styleguide::Controls::Row @name="Unread count"> <Row @name="Unread count">
<input <input
type="number" type="number"
{{on "input" this.updateUnreadCount}} {{on "input" this.updateUnreadCount}}
value={{this.unreadCount}} value={{this.unreadCount}}
/> />
</Styleguide::Controls::Row> </Row>
<Styleguide::Controls::Row @name="Urgent count"> <Row @name="Urgent count">
<input <input
type="number" type="number"
{{on "input" this.updateUrgentCount}} {{on "input" this.updateUrgentCount}}
value={{this.urgentCount}} value={{this.urgentCount}}
/> />
</Styleguide::Controls::Row> </Row>
<Styleguide::Controls::Row @name="Indicator preference"> <Row @name="Indicator preference">
<ComboBox <ComboBox
@value={{this.indicatorPreference}} @value={{this.indicatorPreference}}
@content={{this.indicatorPreferences}} @content={{this.indicatorPreferences}}
@ -107,5 +125,7 @@ export default class ChatStyleguideChatHeaderIcon extends Component {
@nameProperty={{null}} @nameProperty={{null}}
/> />
</Styleguide::Controls::Row> </Row>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -1,10 +1,28 @@
import Component from "@glimmer/component"; import Component from "@glimmer/component";
import { on } from "@ember/modifier";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { service } from "@ember/service"; import { service } from "@ember/service";
import { not } from "truth-helpers";
import DToggleSwitch from "discourse/components/d-toggle-switch";
import { optionalRequire } from "discourse/lib/utilities";
import ChatMessage from "discourse/plugins/chat/discourse/components/chat-message";
import ChatMessagesManager from "discourse/plugins/chat/discourse/lib/chat-messages-manager"; import ChatMessagesManager from "discourse/plugins/chat/discourse/lib/chat-messages-manager";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
const StyleguideComponent = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/component"
);
const Controls = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls"
);
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatMessage extends Component { export default class ChatStyleguideChatMessage extends Component {
@service currentUser; @service currentUser;
@ -92,48 +110,50 @@ export default class ChatStyleguideChatMessage extends Component {
]; ];
} }
} }
}
<template>
<StyleguideExample @title="<ChatMessage>"> <StyleguideExample @title="<ChatMessage>">
<Styleguide::Component> <StyleguideComponent>
<ChatMessage @message={{this.message}} @context="channel" /> <ChatMessage @message={{this.message}} @context="channel" />
</Styleguide::Component> </StyleguideComponent>
<Styleguide::Controls> <Controls>
<Styleguide::Controls::Row @name="Deleted"> <Row @name="Deleted">
<DToggleSwitch <DToggleSwitch
@state={{not (not this.message.deletedAt)}} @state={{not (not this.message.deletedAt)}}
{{on "click" this.toggleDeleted}} {{on "click" this.toggleDeleted}}
/> />
</Styleguide::Controls::Row> </Row>
<Styleguide::Controls::Row @name="Bookmark"> <Row @name="Bookmark">
<DToggleSwitch <DToggleSwitch
@state={{not (not this.message.bookmark)}} @state={{not (not this.message.bookmark)}}
{{on "click" this.toggleBookmarked}} {{on "click" this.toggleBookmarked}}
/> />
</Styleguide::Controls::Row> </Row>
<Styleguide::Controls::Row @name="Thread"> <Row @name="Thread">
<DToggleSwitch <DToggleSwitch
@state={{not (not this.message.thread)}} @state={{not (not this.message.thread)}}
{{on "click" this.toggleThread}} {{on "click" this.toggleThread}}
/> />
</Styleguide::Controls::Row> </Row>
<Styleguide::Controls::Row @name="Reactions"> <Row @name="Reactions">
<DToggleSwitch <DToggleSwitch
@state={{not (not this.message.reactions)}} @state={{not (not this.message.reactions)}}
{{on "click" this.toggleReaction}} {{on "click" this.toggleReaction}}
/> />
</Styleguide::Controls::Row> </Row>
<Styleguide::Controls::Row @name="Upload"> <Row @name="Upload">
<DToggleSwitch <DToggleSwitch
@state={{not (not this.message.uploads)}} @state={{not (not this.message.uploads)}}
{{on "click" this.toggleUpload}} {{on "click" this.toggleUpload}}
/> />
</Styleguide::Controls::Row> </Row>
<Styleguide::Controls::Row @name="Message"> <Row @name="Message">
<textarea <textarea
{{on "input" this.updateMessage}} {{on "input" this.updateMessage}}
>{{this.message.message}}</textarea> >{{this.message.message}}</textarea>
</Styleguide::Controls::Row> </Row>
</Styleguide::Controls> </Controls>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -2,9 +2,18 @@ import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { optionalRequire } from "discourse/lib/utilities";
import ChatModalArchiveChannel from "discourse/plugins/chat/discourse/components/chat/modal/archive-channel"; import ChatModalArchiveChannel from "discourse/plugins/chat/discourse/components/chat/modal/archive-channel";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatModalArchiveChannel extends Component { export default class ChatStyleguideChatModalArchiveChannel extends Component {
@service modal; @service modal;
@ -18,10 +27,12 @@ export default class ChatStyleguideChatModalArchiveChannel extends Component {
}, },
}); });
} }
}
<template>
<StyleguideExample @title="<Chat::Modal::ArchiveChannel>"> <StyleguideExample @title="<Chat::Modal::ArchiveChannel>">
<Styleguide::Controls::Row> <Row>
<DButton @translatedLabel="Open modal" @action={{this.openModal}} /> <DButton @translatedLabel="Open modal" @action={{this.openModal}} />
</Styleguide::Controls::Row> </Row>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -1,8 +1,17 @@
import Component from "@glimmer/component"; import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { optionalRequire } from "discourse/lib/utilities";
import ChatModalCreateChannel from "discourse/plugins/chat/discourse/components/chat/modal/create-channel"; import ChatModalCreateChannel from "discourse/plugins/chat/discourse/components/chat/modal/create-channel";
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatModalCreateChannel extends Component { export default class ChatStyleguideChatModalCreateChannel extends Component {
@service modal; @service modal;
@ -10,10 +19,12 @@ export default class ChatStyleguideChatModalCreateChannel extends Component {
openModal() { openModal() {
return this.modal.show(ChatModalCreateChannel); return this.modal.show(ChatModalCreateChannel);
} }
}
<template>
<StyleguideExample @title="<Chat::Modal::CreateChannel>"> <StyleguideExample @title="<Chat::Modal::CreateChannel>">
<Styleguide::Controls::Row> <Row>
<DButton @translatedLabel="Open modal" @action={{this.openModal}} /> <DButton @translatedLabel="Open modal" @action={{this.openModal}} />
</Styleguide::Controls::Row> </Row>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -2,9 +2,18 @@ import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { optionalRequire } from "discourse/lib/utilities";
import ChatModalDeleteChannel from "discourse/plugins/chat/discourse/components/chat/modal/delete-channel"; import ChatModalDeleteChannel from "discourse/plugins/chat/discourse/components/chat/modal/delete-channel";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatModalDeleteChannel extends Component { export default class ChatStyleguideChatModalDeleteChannel extends Component {
@service modal; @service modal;
@ -16,10 +25,12 @@ export default class ChatStyleguideChatModalDeleteChannel extends Component {
model: { channel: this.channel }, model: { channel: this.channel },
}); });
} }
}
<template>
<StyleguideExample @title="<Chat::Modal::DeleteChannel>"> <StyleguideExample @title="<Chat::Modal::DeleteChannel>">
<Styleguide::Controls::Row> <Row>
<DButton @translatedLabel="Open modal" @action={{this.openModal}} /> <DButton @translatedLabel="Open modal" @action={{this.openModal}} />
</Styleguide::Controls::Row> </Row>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -2,9 +2,18 @@ import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { optionalRequire } from "discourse/lib/utilities";
import ChatModalEditChannelDescription from "discourse/plugins/chat/discourse/components/chat/modal/edit-channel-description"; import ChatModalEditChannelDescription from "discourse/plugins/chat/discourse/components/chat/modal/edit-channel-description";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatModalEditChannelDescription extends Component { export default class ChatStyleguideChatModalEditChannelDescription extends Component {
@service modal; @service modal;
@ -16,10 +25,12 @@ export default class ChatStyleguideChatModalEditChannelDescription extends Compo
model: this.channel, model: this.channel,
}); });
} }
}
<template>
<StyleguideExample @title="<Chat::Modal::EditChannelDescription>"> <StyleguideExample @title="<Chat::Modal::EditChannelDescription>">
<Styleguide::Controls::Row> <Row>
<DButton @translatedLabel="Open modal" @action={{this.openModal}} /> <DButton @translatedLabel="Open modal" @action={{this.openModal}} />
</Styleguide::Controls::Row> </Row>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -2,9 +2,18 @@ import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { optionalRequire } from "discourse/lib/utilities";
import ChatModalEditChannelName from "discourse/plugins/chat/discourse/components/chat/modal/edit-channel-name"; import ChatModalEditChannelName from "discourse/plugins/chat/discourse/components/chat/modal/edit-channel-name";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatModalEditChannelName extends Component { export default class ChatStyleguideChatModalEditChannelName extends Component {
@service modal; @service modal;
@ -16,10 +25,12 @@ export default class ChatStyleguideChatModalEditChannelName extends Component {
model: this.channel, model: this.channel,
}); });
} }
}
<template>
<StyleguideExample @title="<Chat::Modal::EditChannelName>"> <StyleguideExample @title="<Chat::Modal::EditChannelName>">
<Styleguide::Controls::Row> <Row>
<DButton @translatedLabel="Open modal" @action={{this.openModal}} /> <DButton @translatedLabel="Open modal" @action={{this.openModal}} />
</Styleguide::Controls::Row> </Row>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -2,9 +2,18 @@ import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { optionalRequire } from "discourse/lib/utilities";
import ChatModalMoveMessageToChannel from "discourse/plugins/chat/discourse/components/chat/modal/move-message-to-channel"; import ChatModalMoveMessageToChannel from "discourse/plugins/chat/discourse/components/chat/modal/move-message-to-channel";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatModalMoveMessageToChannel extends Component { export default class ChatStyleguideChatModalMoveMessageToChannel extends Component {
@service modal; @service modal;
@ -26,10 +35,12 @@ export default class ChatStyleguideChatModalMoveMessageToChannel extends Compone
}, },
}); });
} }
}
<template>
<StyleguideExample @title="<Chat::Modal::MoveMessageToChannel>"> <StyleguideExample @title="<Chat::Modal::MoveMessageToChannel>">
<Styleguide::Controls::Row> <Row>
<DButton @translatedLabel="Open modal" @action={{this.openModal}} /> <DButton @translatedLabel="Open modal" @action={{this.openModal}} />
</Styleguide::Controls::Row> </Row>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -1,8 +1,17 @@
import Component from "@glimmer/component"; import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { optionalRequire } from "discourse/lib/utilities";
import ChatModalNewMessage from "discourse/plugins/chat/discourse/components/chat/modal/new-message"; import ChatModalNewMessage from "discourse/plugins/chat/discourse/components/chat/modal/new-message";
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatModalNewMessage extends Component { export default class ChatStyleguideChatModalNewMessage extends Component {
@service modal; @service modal;
@ -10,10 +19,12 @@ export default class ChatStyleguideChatModalNewMessage extends Component {
openModal() { openModal() {
return this.modal.show(ChatModalNewMessage); return this.modal.show(ChatModalNewMessage);
} }
}
<template>
<StyleguideExample @title="<Chat::Modal::NewMessage>"> <StyleguideExample @title="<Chat::Modal::NewMessage>">
<Styleguide::Controls::Row> <Row>
<DButton @translatedLabel="Open modal" @action={{this.openModal}} /> <DButton @translatedLabel="Open modal" @action={{this.openModal}} />
</Styleguide::Controls::Row> </Row>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -2,9 +2,18 @@ import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { optionalRequire } from "discourse/lib/utilities";
import ChatModalThreadSettings from "discourse/plugins/chat/discourse/components/chat/modal/thread-settings"; import ChatModalThreadSettings from "discourse/plugins/chat/discourse/components/chat/modal/thread-settings";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatModalThreadSettings extends Component { export default class ChatStyleguideChatModalThreadSettings extends Component {
@service modal; @service modal;
@ -14,10 +23,12 @@ export default class ChatStyleguideChatModalThreadSettings extends Component {
model: new ChatFabricators(getOwner(this)).thread(), model: new ChatFabricators(getOwner(this)).thread(),
}); });
} }
}
<template>
<StyleguideExample @title="<Chat::Modal::ThreadSettings>"> <StyleguideExample @title="<Chat::Modal::ThreadSettings>">
<Styleguide::Controls::Row> <Row>
<DButton @translatedLabel="Open modal" @action={{this.openModal}} /> <DButton @translatedLabel="Open modal" @action={{this.openModal}} />
</Styleguide::Controls::Row> </Row>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -2,9 +2,18 @@ import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { service } from "@ember/service"; import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { optionalRequire } from "discourse/lib/utilities";
import ChatModalToggleChannelStatus from "discourse/plugins/chat/discourse/components/chat/modal/toggle-channel-status"; import ChatModalToggleChannelStatus from "discourse/plugins/chat/discourse/components/chat/modal/toggle-channel-status";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
const Row = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/controls/row"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatModalToggleChannelStatus extends Component { export default class ChatStyleguideChatModalToggleChannelStatus extends Component {
@service modal; @service modal;
@ -14,10 +23,12 @@ export default class ChatStyleguideChatModalToggleChannelStatus extends Componen
model: new ChatFabricators(getOwner(this)).channel(), model: new ChatFabricators(getOwner(this)).channel(),
}); });
} }
}
<template>
<StyleguideExample @title="<Chat::Modal::ToggleChannelStatus>"> <StyleguideExample @title="<Chat::Modal::ToggleChannelStatus>">
<Styleguide::Controls::Row> <Row>
<DButton @translatedLabel="Open modal" @action={{this.openModal}} /> <DButton @translatedLabel="Open modal" @action={{this.openModal}} />
</Styleguide::Controls::Row> </Row>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -3,8 +3,17 @@ import { tracked } from "@glimmer/tracking";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import { next } from "@ember/runloop"; import { next } from "@ember/runloop";
import { service } from "@ember/service"; import { service } from "@ember/service";
import { optionalRequire } from "discourse/lib/utilities";
import Item from "discourse/plugins/chat/discourse/components/chat/thread-list/item";
import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators"; import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
const StyleguideComponent = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide/component"
);
const StyleguideExample = optionalRequire(
"discourse/plugins/styleguide/discourse/components/styleguide-example"
);
export default class ChatStyleguideChatThreadListItem extends Component { export default class ChatStyleguideChatThreadListItem extends Component {
@service currentUser; @service currentUser;
@ -17,12 +26,14 @@ export default class ChatStyleguideChatThreadListItem extends Component {
this.thread = new ChatFabricators(getOwner(this)).thread(); this.thread = new ChatFabricators(getOwner(this)).thread();
}); });
} }
}
<template>
<StyleguideExample @title="<Chat::ThreadList::Item>"> <StyleguideExample @title="<Chat::ThreadList::Item>">
<Styleguide::Component> <StyleguideComponent>
{{#if this.thread}} {{#if this.thread}}
<Chat::ThreadList::Item @thread={{this.thread}} /> <Item @thread={{this.thread}} />
{{/if}} {{/if}}
</Styleguide::Component> </StyleguideComponent>
</StyleguideExample> </StyleguideExample>
</template>
}

View File

@ -1,14 +1,25 @@
import Component from "@ember/component"; import Component from "@ember/component";
import { fn, hash } from "@ember/helper";
import { on } from "@ember/modifier";
import EmberObject, { action } from "@ember/object"; import EmberObject, { action } from "@ember/object";
import { notEmpty } from "@ember/object/computed"; import { notEmpty } from "@ember/object/computed";
import { schedule } from "@ember/runloop"; import { schedule } from "@ember/runloop";
import { observes } from "@ember-decorators/object"; import { observes } from "@ember-decorators/object";
import CalendarDateTimeInput from "discourse/components/calendar-date-time-input";
import DButton from "discourse/components/d-button";
import DModal from "discourse/components/d-modal";
import TextField from "discourse/components/text-field";
import icon from "discourse/helpers/d-icon";
import htmlSafe from "discourse/helpers/html-safe";
import { propertyNotEqual } from "discourse/lib/computed"; import { propertyNotEqual } from "discourse/lib/computed";
import computed, { debounce } from "discourse/lib/decorators"; import computed, { debounce } from "discourse/lib/decorators";
import { INPUT_DELAY } from "discourse/lib/environment"; import { INPUT_DELAY } from "discourse/lib/environment";
import { applyLocalDates } from "discourse/lib/local-dates"; import { applyLocalDates } from "discourse/lib/local-dates";
import { cook } from "discourse/lib/text"; import { cook } from "discourse/lib/text";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import ComboBox from "select-kit/components/combo-box";
import MultiSelect from "select-kit/components/multi-select";
import TimezoneInput from "select-kit/components/timezone-input";
import generateDateMarkup from "discourse/plugins/discourse-local-dates/lib/local-date-markup-generator"; import generateDateMarkup from "discourse/plugins/discourse-local-dates/lib/local-date-markup-generator";
export default class LocalDatesCreate extends Component { export default class LocalDatesCreate extends Component {
@ -371,8 +382,8 @@ export default class LocalDatesCreate extends Component {
cancel() { cancel() {
this.closeModal(); this.closeModal();
} }
}
<template>
<DModal <DModal
@title={{i18n "discourse_local_dates.title"}} @title={{i18n "discourse_local_dates.title"}}
@closeModal={{@closeModal}} @closeModal={{@closeModal}}
@ -384,7 +395,8 @@ export default class LocalDatesCreate extends Component {
{{#if this.timezoneIsDifferentFromUserTimezone}} {{#if this.timezoneIsDifferentFromUserTimezone}}
<div class="preview alert alert-info"> <div class="preview alert alert-info">
{{i18n "discourse_local_dates.create.form.current_timezone"}} {{i18n "discourse_local_dates.create.form.current_timezone"}}
<b>{{this.formattedCurrentUserTimezone}}</b>{{this.currentPreview}} <b
>{{this.formattedCurrentUserTimezone}}</b>{{this.currentPreview}}
</div> </div>
{{/if}} {{/if}}
{{else}} {{else}}
@ -402,7 +414,7 @@ export default class LocalDatesCreate extends Component {
{{if this.fromSelected 'is-selected'}} {{if this.fromSelected 'is-selected'}}
{{if this.fromFilled 'is-filled'}}" {{if this.fromFilled 'is-filled'}}"
> >
{{d-icon "calendar-days"}} {{icon "calendar-days"}}
<DButton <DButton
@action={{this.focusFrom}} @action={{this.focusFrom}}
@translatedLabel={{this.formattedFrom}} @translatedLabel={{this.formattedFrom}}
@ -417,7 +429,7 @@ export default class LocalDatesCreate extends Component {
{{if this.toSelected 'is-selected'}} {{if this.toSelected 'is-selected'}}
{{if this.toFilled 'is-filled'}}" {{if this.toFilled 'is-filled'}}"
> >
{{d-icon "calendar-days"}} {{icon "calendar-days"}}
<DButton <DButton
@action={{this.focusTo}} @action={{this.focusTo}}
@translatedLabel={{this.formattedTo}} @translatedLabel={{this.formattedTo}}
@ -470,7 +482,7 @@ export default class LocalDatesCreate extends Component {
<label class="control-label"> <label class="control-label">
{{i18n "discourse_local_dates.create.form.recurring_title"}} {{i18n "discourse_local_dates.create.form.recurring_title"}}
</label> </label>
<p>{{html-safe <p>{{htmlSafe
(i18n (i18n
"discourse_local_dates.create.form.recurring_description" "discourse_local_dates.create.form.recurring_description"
) )
@ -513,13 +525,15 @@ export default class LocalDatesCreate extends Component {
"discourse_local_dates.create.form.format_title" "discourse_local_dates.create.form.format_title"
}}</label> }}</label>
<p> <p>
{{i18n "discourse_local_dates.create.form.format_description"}} {{i18n
"discourse_local_dates.create.form.format_description"
}}
<a <a
target="_blank" target="_blank"
href="https://momentjs.com/docs/#/parsing/string-format/" href="https://momentjs.com/docs/#/parsing/string-format/"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
{{d-icon "circle-question"}} {{icon "circle-question"}}
</a> </a>
</p> </p>
<div class="controls"> <div class="controls">
@ -533,7 +547,10 @@ export default class LocalDatesCreate extends Component {
<a <a
class="moment-format" class="moment-format"
href href
{{on "click" (fn this.updateFormat previewedFormat.format)}} {{on
"click"
(fn this.updateFormat previewedFormat.format)
}}
> >
{{previewedFormat.format}} {{previewedFormat.format}}
</a> </a>
@ -573,3 +590,5 @@ export default class LocalDatesCreate extends Component {
/> />
</:footer> </:footer>
</DModal> </DModal>
</template>
}

View File

@ -1 +1,8 @@
import ComposerPresenceDisplay from "discourse/plugins/discourse-presence/discourse/components/composer-presence-display";
const Presence = <template>
<div class="before-composer-controls-outlet presence">
<ComposerPresenceDisplay @model={{@outletArgs.model}} /> <ComposerPresenceDisplay @model={{@outletArgs.model}} />
</div>
</template>;
export default Presence;

View File

@ -1 +1,8 @@
import TopicPresenceDisplay from "discourse/plugins/discourse-presence/discourse/components/topic-presence-display";
const Presence = <template>
<div class="topic-above-footer-buttons-outlet presence">
<TopicPresenceDisplay @topic={{@outletArgs.model}} /> <TopicPresenceDisplay @topic={{@outletArgs.model}} />
</div>
</template>;
export default Presence;

View File

@ -1,13 +1,21 @@
import Component from "@ember/component"; import Component from "@ember/component";
import { fn, get } from "@ember/helper";
import { on } from "@ember/modifier";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { service } from "@ember/service"; import { service } from "@ember/service";
import { classify } from "@ember/string"; import { classify } from "@ember/string";
import { htmlSafe } from "@ember/template"; import { htmlSafe } from "@ember/template";
import { eq } from "truth-helpers";
import DModal from "discourse/components/d-modal";
import concatClass from "discourse/helpers/concat-class";
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import discourseComputed from "discourse/lib/decorators"; import discourseComputed from "discourse/lib/decorators";
import loadScript from "discourse/lib/load-script"; import loadScript from "discourse/lib/load-script";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import ComboBox from "select-kit/components/combo-box";
import PollBreakdownChart from "discourse/plugins/poll/discourse/components/poll-breakdown-chart";
import PollBreakdownOption from "discourse/plugins/poll/discourse/components/poll-breakdown-option";
export default class PollBreakdownModal extends Component { export default class PollBreakdownModal extends Component {
@service dialog; @service dialog;
@ -88,8 +96,8 @@ export default class PollBreakdownModal extends Component {
onSelectPanel(panel) { onSelectPanel(panel) {
this.set("displayMode", panel.id); this.set("displayMode", panel.id);
} }
}
<template>
{{! template-lint-disable no-invalid-interactive }} {{! template-lint-disable no-invalid-interactive }}
<DModal <DModal
@title={{i18n "poll.breakdown.title"}} @title={{i18n "poll.breakdown.title"}}
@ -99,14 +107,14 @@ export default class PollBreakdownModal extends Component {
<:headerBelowTitle> <:headerBelowTitle>
<ul class="modal-tabs"> <ul class="modal-tabs">
<li <li
class={{concat-class class={{concatClass
"modal-tab percentage" "modal-tab percentage"
(if (eq this.displayMode "percentage") "is-active") (if (eq this.displayMode "percentage") "is-active")
}} }}
{{on "click" (fn (mut this.displayMode) "percentage")}} {{on "click" (fn (mut this.displayMode) "percentage")}}
>{{i18n "poll.breakdown.percentage"}}</li> >{{i18n "poll.breakdown.percentage"}}</li>
<li <li
class={{concat-class class={{concatClass
"modal-tab count" "modal-tab count"
(if (eq this.displayMode "count") "is-active") (if (eq this.displayMode "count") "is-active")
}} }}
@ -170,3 +178,5 @@ export default class PollBreakdownModal extends Component {
</div> </div>
</:body> </:body>
</DModal> </DModal>
</template>
}

View File

@ -1,10 +1,24 @@
import Component from "@ember/component"; import Component, { Input, Textarea } from "@ember/component";
import { fn } from "@ember/helper";
import { on } from "@ember/modifier";
import EmberObject, { action } from "@ember/object"; import EmberObject, { action } from "@ember/object";
import { gt, or } from "@ember/object/computed"; import { gt, or } from "@ember/object/computed";
import { service } from "@ember/service"; import { service } from "@ember/service";
import { observes } from "@ember-decorators/object"; import { observes } from "@ember-decorators/object";
import { and, not } from "truth-helpers";
import DButton from "discourse/components/d-button";
import DModal from "discourse/components/d-modal";
import DToggleSwitch from "discourse/components/d-toggle-switch";
import DateTimeInput from "discourse/components/date-time-input";
import InputTip from "discourse/components/input-tip";
import RadioButton from "discourse/components/radio-button";
import concatClass from "discourse/helpers/concat-class";
import icon from "discourse/helpers/d-icon";
import discourseComputed from "discourse/lib/decorators"; import discourseComputed from "discourse/lib/decorators";
import autoFocus from "discourse/modifiers/auto-focus";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import ComboBox from "select-kit/components/combo-box";
import GroupChooser from "select-kit/components/group-chooser";
export const BAR_CHART_TYPE = "bar"; export const BAR_CHART_TYPE = "bar";
export const PIE_CHART_TYPE = "pie"; export const PIE_CHART_TYPE = "pie";
@ -396,8 +410,8 @@ export default class PollUiBuilderModal extends Component {
togglePublic() { togglePublic() {
this.set("publicPoll", !this.publicPoll); this.set("publicPoll", !this.publicPoll);
} }
}
<template>
<DModal <DModal
@title={{i18n "poll.ui_builder.title"}} @title={{i18n "poll.ui_builder.title"}}
@closeModal={{@closeModal}} @closeModal={{@closeModal}}
@ -486,7 +500,7 @@ export default class PollUiBuilderModal extends Component {
<input <input
type="text" type="text"
value={{option.value}} value={{option.value}}
{{auto-focus}} {{autoFocus}}
{{on "input" (fn this.updateValue option)}} {{on "input" (fn this.updateValue option)}}
{{on "keydown" (fn this.onInputKeydown index)}} {{on "keydown" (fn this.onInputKeydown index)}}
/> />
@ -626,7 +640,7 @@ export default class PollUiBuilderModal extends Component {
@value="bar" @value="bar"
@selection={{this.chartType}} @selection={{this.chartType}}
/> />
<label for="poll-chart-type-bar">{{d-icon "chart-bar"}} <label for="poll-chart-type-bar">{{icon "chart-bar"}}
{{i18n "poll.ui_builder.poll_chart_type.bar"}}</label> {{i18n "poll.ui_builder.poll_chart_type.bar"}}</label>
</div> </div>
@ -637,7 +651,7 @@ export default class PollUiBuilderModal extends Component {
@value="pie" @value="pie"
@selection={{this.chartType}} @selection={{this.chartType}}
/> />
<label for="poll-chart-type-pie">{{d-icon "chart-pie"}} <label for="poll-chart-type-pie">{{icon "chart-pie"}}
{{i18n "poll.ui_builder.poll_chart_type.pie"}}</label> {{i18n "poll.ui_builder.poll_chart_type.pie"}}</label>
</div> </div>
</div> </div>
@ -668,3 +682,5 @@ export default class PollUiBuilderModal extends Component {
</:footer> </:footer>
</DModal> </DModal>
</template>
}

View File

@ -1,13 +1,15 @@
import { click, render } from "@ember/test-helpers"; import { click, render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import PollButtonsDropdown from "discourse/plugins/poll/discourse/components/poll-buttons-dropdown";
module("Poll | Component | poll-buttons-dropdown", function (hooks) { module("Poll | Component | poll-buttons-dropdown", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
test("Renders a clickable dropdown menu with a close option", async function (assert) { test("Renders a clickable dropdown menu with a close option", async function (assert) {
const self = this;
this.siteSettings.data_explorer_enabled = true; this.siteSettings.data_explorer_enabled = true;
this.siteSettings.poll_export_data_explorer_query_id = 18; this.siteSettings.poll_export_data_explorer_query_id = 18;
this.currentUser.setProperties({ admin: true }); this.currentUser.setProperties({ admin: true });
@ -23,16 +25,20 @@ module("Poll | Component | poll-buttons-dropdown", function (hooks) {
dropDownClick: () => {}, dropDownClick: () => {},
}); });
await render(hbs`<PollButtonsDropdown await render(
@closed={{this.closed}} <template>
@voters={{this.voters}} <PollButtonsDropdown
@isStaff={{this.isStaff}} @closed={{self.closed}}
@isMe={{this.isMe}} @voters={{self.voters}}
@topicArchived={{this.topicArchived}} @isStaff={{self.isStaff}}
@groupableUserFields={{this.groupableUserFields}} @isMe={{self.isMe}}
@isAutomaticallyClosed={{this.isAutomaticallyClosed}} @topicArchived={{self.topicArchived}}
@dropDownClick={{this.dropDownClick}} @groupableUserFields={{self.groupableUserFields}}
/>`); @isAutomaticallyClosed={{self.isAutomaticallyClosed}}
@dropDownClick={{self.dropDownClick}}
/>
</template>
);
await click(".widget-dropdown-header"); await click(".widget-dropdown-header");
@ -46,6 +52,8 @@ module("Poll | Component | poll-buttons-dropdown", function (hooks) {
}); });
test("Renders a show-tally button when poll is a bar chart", async function (assert) { test("Renders a show-tally button when poll is a bar chart", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
closed: false, closed: false,
voters: 2, voters: 2,
@ -58,17 +66,21 @@ module("Poll | Component | poll-buttons-dropdown", function (hooks) {
availableDisplayMode: "showTally", availableDisplayMode: "showTally",
}); });
await render(hbs`<PollButtonsDropdown await render(
@closed={{this.closed}} <template>
@voters={{this.voters}} <PollButtonsDropdown
@isStaff={{this.isStaff}} @closed={{self.closed}}
@isMe={{this.isMe}} @voters={{self.voters}}
@topicArchived={{this.topicArchived}} @isStaff={{self.isStaff}}
@groupableUserFields={{this.groupableUserFields}} @isMe={{self.isMe}}
@isAutomaticallyClosed={{this.isAutomaticallyClosed}} @topicArchived={{self.topicArchived}}
@dropDownClick={{this.dropDownClick}} @groupableUserFields={{self.groupableUserFields}}
@availableDisplayMode={{this.availableDisplayMode}} @isAutomaticallyClosed={{self.isAutomaticallyClosed}}
/>`); @dropDownClick={{self.dropDownClick}}
@availableDisplayMode={{self.availableDisplayMode}}
/>
</template>
);
await click(".widget-dropdown-header"); await click(".widget-dropdown-header");
@ -82,6 +94,8 @@ module("Poll | Component | poll-buttons-dropdown", function (hooks) {
}); });
test("Renders a single button when there is only one authorised action", async function (assert) { test("Renders a single button when there is only one authorised action", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
closed: false, closed: false,
voters: 2, voters: 2,
@ -93,16 +107,20 @@ module("Poll | Component | poll-buttons-dropdown", function (hooks) {
dropDownClick: () => {}, dropDownClick: () => {},
}); });
await render(hbs`<PollButtonsDropdown await render(
@closed={{this.closed}} <template>
@voters={{this.voters}} <PollButtonsDropdown
@isStaff={{this.isStaff}} @closed={{self.closed}}
@isMe={{this.isMe}} @voters={{self.voters}}
@topicArchived={{this.topicArchived}} @isStaff={{self.isStaff}}
@groupableUserFields={{this.groupableUserFields}} @isMe={{self.isMe}}
@isAutomaticallyClosed={{this.isAutomaticallyClosed}} @topicArchived={{self.topicArchived}}
@dropDownClick={{this.dropDownClick}} @groupableUserFields={{self.groupableUserFields}}
/>`); @isAutomaticallyClosed={{self.isAutomaticallyClosed}}
@dropDownClick={{self.dropDownClick}}
/>
</template>
);
assert.dom(".widget-dropdown-header").doesNotExist(); assert.dom(".widget-dropdown-header").doesNotExist();
assert.dom("button.widget-button").exists({ count: 1 }); assert.dom("button.widget-button").exists({ count: 1 });
@ -115,6 +133,8 @@ module("Poll | Component | poll-buttons-dropdown", function (hooks) {
}); });
test("Doesn't render a button when user has no authorised actions", async function (assert) { test("Doesn't render a button when user has no authorised actions", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
closed: false, closed: false,
voters: 0, voters: 0,
@ -126,16 +146,20 @@ module("Poll | Component | poll-buttons-dropdown", function (hooks) {
dropDownClick: () => {}, dropDownClick: () => {},
}); });
await render(hbs`<PollButtonsDropdown await render(
@closed={{this.closed}} <template>
@voters={{this.voters}} <PollButtonsDropdown
@isStaff={{this.isStaff}} @closed={{self.closed}}
@isMe={{this.isMe}} @voters={{self.voters}}
@topicArchived={{this.topicArchived}} @isStaff={{self.isStaff}}
@groupableUserFields={{this.groupableUserFields}} @isMe={{self.isMe}}
@isAutomaticallyClosed={{this.isAutomaticallyClosed}} @topicArchived={{self.topicArchived}}
@dropDownClick={{this.dropDownClick}} @groupableUserFields={{self.groupableUserFields}}
/>`); @isAutomaticallyClosed={{self.isAutomaticallyClosed}}
@dropDownClick={{self.dropDownClick}}
/>
</template>
);
assert.dom(".widget-dropdown-header").doesNotExist(); assert.dom(".widget-dropdown-header").doesNotExist();
assert.dom("button.widget-button").doesNotExist(); assert.dom("button.widget-button").doesNotExist();

View File

@ -1,8 +1,8 @@
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import PollInfo from "discourse/plugins/poll/discourse/components/poll-info";
const OPTIONS = [ const OPTIONS = [
{ id: "1ddc47be0d2315b9711ee8526ca9d83f", html: "This", votes: 2, rank: 0 }, { id: "1ddc47be0d2315b9711ee8526ca9d83f", html: "This", votes: 2, rank: 0 },
@ -14,6 +14,8 @@ module("Poll | Component | poll-info", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
test("public multiple poll with results anytime", async function (assert) { test("public multiple poll with results anytime", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
isMultiple: true, isMultiple: true,
min: 1, min: 1,
@ -29,20 +31,24 @@ module("Poll | Component | poll-info", function (hooks) {
voters: [], voters: [],
}); });
await render(hbs`<PollInfo await render(
@options={{this.options}} <template>
@min={{this.min}} <PollInfo
@max={{this.max}} @options={{self.options}}
@isMultiple={{this.isMultiple}} @min={{self.min}}
@close={{this.close}} @max={{self.max}}
@closed={{this.closed}} @isMultiple={{self.isMultiple}}
@results={{this.results}} @close={{self.close}}
@showResults={{this.showResults}} @closed={{self.closed}}
@postUserId={{this.postUserId}} @results={{self.results}}
@isPublic={{this.isPublic}} @showResults={{self.showResults}}
@hasVoted={{this.hasVoted}} @postUserId={{self.postUserId}}
@voters={{this.voters}} @isPublic={{self.isPublic}}
/>`); @hasVoted={{self.hasVoted}}
@voters={{self.voters}}
/>
</template>
);
assert.dom(".poll-info_instructions li.multiple-help-text").hasText( assert.dom(".poll-info_instructions li.multiple-help-text").hasText(
i18n("poll.multiple.help.up_to_max_options", { i18n("poll.multiple.help.up_to_max_options", {
@ -60,6 +66,8 @@ module("Poll | Component | poll-info", function (hooks) {
}); });
test("public multiple poll with results only shown on vote", async function (assert) { test("public multiple poll with results only shown on vote", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
isMultiple: true, isMultiple: true,
min: 1, min: 1,
@ -75,20 +83,24 @@ module("Poll | Component | poll-info", function (hooks) {
voters: [], voters: [],
}); });
await render(hbs`<PollInfo await render(
@options={{this.options}} <template>
@min={{this.min}} <PollInfo
@max={{this.max}} @options={{self.options}}
@isMultiple={{this.isMultiple}} @min={{self.min}}
@close={{this.close}} @max={{self.max}}
@closed={{this.closed}} @isMultiple={{self.isMultiple}}
@results={{this.results}} @close={{self.close}}
@showResults={{this.showResults}} @closed={{self.closed}}
@postUserId={{this.postUserId}} @results={{self.results}}
@isPublic={{this.isPublic}} @showResults={{self.showResults}}
@hasVoted={{this.hasVoted}} @postUserId={{self.postUserId}}
@voters={{this.voters}} @isPublic={{self.isPublic}}
/>`); @hasVoted={{self.hasVoted}}
@voters={{self.voters}}
/>
</template>
);
assert.dom(".poll-info_instructions li.multiple-help-text").hasText( assert.dom(".poll-info_instructions li.multiple-help-text").hasText(
i18n("poll.multiple.help.up_to_max_options", { i18n("poll.multiple.help.up_to_max_options", {

View File

@ -1,8 +1,8 @@
import { click, render } from "@ember/test-helpers"; import { click, render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import PollOptions from "discourse/plugins/poll/discourse/components/poll-options";
const OPTIONS = [ const OPTIONS = [
{ id: "1ddc47be0d2315b9711ee8526ca9d83f", html: "This", votes: 0, rank: 0 }, { id: "1ddc47be0d2315b9711ee8526ca9d83f", html: "This", votes: 0, rank: 0 },
@ -29,6 +29,8 @@ module("Poll | Component | poll-options", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
test("single, not selected", async function (assert) { test("single, not selected", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
isCheckbox: false, isCheckbox: false,
isRankedChoice: false, isRankedChoice: false,
@ -37,19 +39,25 @@ module("Poll | Component | poll-options", function (hooks) {
votes: [], votes: [],
}); });
await render(hbs`<PollOptions await render(
@isCheckbox={{this.isCheckbox}} <template>
@isRankedChoice={{this.isRankedChoice}} <PollOptions
@ranked_choice_dropdown_content={{this.ranked_choice_dropdown_content}} @isCheckbox={{self.isCheckbox}}
@options={{this.options}} @isRankedChoice={{self.isRankedChoice}}
@votes={{this.votes}} @ranked_choice_dropdown_content={{self.ranked_choice_dropdown_content}}
@sendRadioClick={{this.toggleOption}} @options={{self.options}}
/>`); @votes={{self.votes}}
@sendRadioClick={{self.toggleOption}}
/>
</template>
);
assert.dom("li .d-icon-far-circle:nth-of-type(1)").exists({ count: 3 }); assert.dom("li .d-icon-far-circle:nth-of-type(1)").exists({ count: 3 });
}); });
test("single, selected", async function (assert) { test("single, selected", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
isCheckbox: false, isCheckbox: false,
isRankedChoice: false, isRankedChoice: false,
@ -58,19 +66,25 @@ module("Poll | Component | poll-options", function (hooks) {
votes: ["6c986ebcde3d5822a6e91a695c388094"], votes: ["6c986ebcde3d5822a6e91a695c388094"],
}); });
await render(hbs`<PollOptions await render(
@isCheckbox={{this.isCheckbox}} <template>
@isRankedChoice={{this.isRankedChoice}} <PollOptions
@ranked_choice_dropdown_content={{this.ranked_choice_dropdown_content}} @isCheckbox={{self.isCheckbox}}
@options={{this.options}} @isRankedChoice={{self.isRankedChoice}}
@votes={{this.votes}} @ranked_choice_dropdown_content={{self.ranked_choice_dropdown_content}}
@sendRadioClick={{this.toggleOption}} @options={{self.options}}
/>`); @votes={{self.votes}}
@sendRadioClick={{self.toggleOption}}
/>
</template>
);
assert.dom("li .d-icon-circle:nth-of-type(1)").exists({ count: 1 }); assert.dom("li .d-icon-circle:nth-of-type(1)").exists({ count: 1 });
}); });
test("multi, not selected", async function (assert) { test("multi, not selected", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
isCheckbox: true, isCheckbox: true,
isRankedChoice: false, isRankedChoice: false,
@ -79,19 +93,25 @@ module("Poll | Component | poll-options", function (hooks) {
votes: [], votes: [],
}); });
await render(hbs`<PollOptions await render(
@isCheckbox={{this.isCheckbox}} <template>
@isRankedChoice={{this.isRankedChoice}} <PollOptions
@ranked_choice_dropdown_content={{this.ranked_choice_dropdown_content}} @isCheckbox={{self.isCheckbox}}
@options={{this.options}} @isRankedChoice={{self.isRankedChoice}}
@votes={{this.votes}} @ranked_choice_dropdown_content={{self.ranked_choice_dropdown_content}}
@sendRadioClick={{this.toggleOption}} @options={{self.options}}
/>`); @votes={{self.votes}}
@sendRadioClick={{self.toggleOption}}
/>
</template>
);
assert.dom("li .d-icon-far-square:nth-of-type(1)").exists({ count: 3 }); assert.dom("li .d-icon-far-square:nth-of-type(1)").exists({ count: 3 });
}); });
test("multi, selected", async function (assert) { test("multi, selected", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
isCheckbox: true, isCheckbox: true,
isRankedChoice: false, isRankedChoice: false,
@ -100,14 +120,18 @@ module("Poll | Component | poll-options", function (hooks) {
votes: ["6c986ebcde3d5822a6e91a695c388094"], votes: ["6c986ebcde3d5822a6e91a695c388094"],
}); });
await render(hbs`<PollOptions await render(
@isCheckbox={{this.isCheckbox}} <template>
@isRankedChoice={{this.isRankedChoice}} <PollOptions
@ranked_choice_dropdown_content={{this.ranked_choice_dropdown_content}} @isCheckbox={{self.isCheckbox}}
@options={{this.options}} @isRankedChoice={{self.isRankedChoice}}
@votes={{this.votes}} @ranked_choice_dropdown_content={{self.ranked_choice_dropdown_content}}
@sendRadioClick={{this.toggleOption}} @options={{self.options}}
/>`); @votes={{self.votes}}
@sendRadioClick={{self.toggleOption}}
/>
</template>
);
assert assert
.dom("li .d-icon-far-square-check:nth-of-type(1)") .dom("li .d-icon-far-square-check:nth-of-type(1)")
@ -115,23 +139,31 @@ module("Poll | Component | poll-options", function (hooks) {
}); });
test("single with images", async function (assert) { test("single with images", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
isCheckbox: false, isCheckbox: false,
options: IMAGE_OPTIONS, options: IMAGE_OPTIONS,
votes: [], votes: [],
}); });
await render(hbs`<PollOptions await render(
@isCheckbox={{this.isCheckbox}} <template>
@options={{this.options}} <PollOptions
@votes={{this.votes}} @isCheckbox={{self.isCheckbox}}
@sendRadioClick={{this.toggleOption}} @options={{self.options}}
/>`); @votes={{self.votes}}
@sendRadioClick={{self.toggleOption}}
/>
</template>
);
assert.dom("li img").exists({ count: 2 }); assert.dom("li img").exists({ count: 2 });
}); });
test("ranked choice - priorities", async function (assert) { test("ranked choice - priorities", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
isCheckbox: false, isCheckbox: false,
isRankedChoice: true, isRankedChoice: true,
@ -140,14 +172,18 @@ module("Poll | Component | poll-options", function (hooks) {
votes: [], votes: [],
}); });
await render(hbs`<PollOptions await render(
@isCheckbox={{this.isCheckbox}} <template>
@isRankedChoice={{this.isRankedChoice}} <PollOptions
@ranked_choice_dropdown_content={{this.ranked_choice_dropdown_content}} @isCheckbox={{self.isCheckbox}}
@options={{this.options}} @isRankedChoice={{self.isRankedChoice}}
@votes={{this.votes}} @ranked_choice_dropdown_content={{self.ranked_choice_dropdown_content}}
@sendRadioClick={{this.toggleOption}} @options={{self.options}}
/>`); @votes={{self.votes}}
@sendRadioClick={{self.toggleOption}}
/>
</template>
);
await click( await click(
`.ranked-choice-poll-option[data-poll-option-id='${OPTIONS[0].id}'] button` `.ranked-choice-poll-option[data-poll-option-id='${OPTIONS[0].id}'] button`

View File

@ -1,7 +1,7 @@
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import PollResultsPie from "discourse/plugins/poll/discourse/components/poll-results-pie";
const OPTIONS = [ const OPTIONS = [
{ id: "1ddc47be0d2315b9711ee8526ca9d83f", html: "This", votes: 3, rank: 0 }, { id: "1ddc47be0d2315b9711ee8526ca9d83f", html: "This", votes: 3, rank: 0 },
@ -15,13 +15,17 @@ module("Poll | Component | poll-results-pie", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
test("Renders the pie chart Component correctly", async function (assert) { test("Renders the pie chart Component correctly", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
id: ID, id: ID,
options: OPTIONS, options: OPTIONS,
}); });
await render( await render(
hbs`<PollResultsPie @id={{this.id}} @options={{this.options}} />` <template>
<PollResultsPie @id={{self.id}} @options={{self.options}} />
</template>
); );
assert.dom("li.legend").exists({ count: 3 }); assert.dom("li.legend").exists({ count: 3 });

View File

@ -1,8 +1,8 @@
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import PollResultsRankedChoice from "discourse/plugins/poll/discourse/components/poll-results-ranked-choice";
const RANKED_CHOICE_OUTCOME = { const RANKED_CHOICE_OUTCOME = {
tied: false, tied: false,
@ -34,12 +34,18 @@ module("Poll | Component | poll-results-ranked-choice", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
test("Renders the ranked choice results component correctly", async function (assert) { test("Renders the ranked choice results component correctly", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
rankedChoiceOutcome: RANKED_CHOICE_OUTCOME, rankedChoiceOutcome: RANKED_CHOICE_OUTCOME,
}); });
await render( await render(
hbs`<PollResultsRankedChoice @rankedChoiceOutcome={{this.rankedChoiceOutcome}} />` <template>
<PollResultsRankedChoice
@rankedChoiceOutcome={{self.rankedChoiceOutcome}}
/>
</template>
); );
assert assert
@ -56,10 +62,16 @@ module("Poll | Component | poll-results-ranked-choice", function (hooks) {
}); });
test("Renders the ranked choice results component without error when outcome data is empty", async function (assert) { test("Renders the ranked choice results component without error when outcome data is empty", async function (assert) {
const self = this;
this.rankedChoiceOutcome = null; this.rankedChoiceOutcome = null;
await render( await render(
hbs`<PollResultsRankedChoice @rankedChoiceOutcome={{this.rankedChoiceOutcome}} />` <template>
<PollResultsRankedChoice
@rankedChoiceOutcome={{self.rankedChoiceOutcome}}
/>
</template>
); );
assert assert

View File

@ -1,9 +1,9 @@
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { queryAll } from "discourse/tests/helpers/qunit-helpers"; import { queryAll } from "discourse/tests/helpers/qunit-helpers";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import PollResultsStandard from "discourse/plugins/poll/discourse/components/poll-results-standard";
const TWO_OPTIONS = [ const TWO_OPTIONS = [
{ id: "1ddc47be0d2315b9711ee8526ca9d83f", html: "This", votes: 5, rank: 0 }, { id: "1ddc47be0d2315b9711ee8526ca9d83f", html: "This", votes: 5, rank: 0 },
@ -38,6 +38,8 @@ module("Poll | Component | poll-results-standard", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
test("Renders the standard results Component correctly", async function (assert) { test("Renders the standard results Component correctly", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
options: TWO_OPTIONS, options: TWO_OPTIONS,
pollName: "Two Choice Poll", pollName: "Two Choice Poll",
@ -50,17 +52,21 @@ module("Poll | Component | poll-results-standard", function (hooks) {
fetchVoters: () => {}, fetchVoters: () => {},
}); });
await render(hbs`<PollResultsStandard await render(
@options={{this.options}} <template>
@pollName={{this.pollName}} <PollResultsStandard
@pollType={{this.pollType}} @options={{self.options}}
@isPublic={{this.isPublic}} @pollName={{self.pollName}}
@postId={{this.postId}} @pollType={{self.pollType}}
@vote={{this.vote}} @isPublic={{self.isPublic}}
@voters={{this.voters}} @postId={{self.postId}}
@votersCount={{this.votersCount}} @vote={{self.vote}}
@fetchVoters={{this.fetchVoters}} @voters={{self.voters}}
/>`); @votersCount={{self.votersCount}}
@fetchVoters={{self.fetchVoters}}
/>
</template>
);
assert.dom(queryAll(".option .percentage")[0]).hasText("56%"); assert.dom(queryAll(".option .percentage")[0]).hasText("56%");
assert.dom(queryAll(".option .percentage")[1]).hasText("44%"); assert.dom(queryAll(".option .percentage")[1]).hasText("44%");
@ -68,6 +74,8 @@ module("Poll | Component | poll-results-standard", function (hooks) {
}); });
test("Omits voters for private polls", async function (assert) { test("Omits voters for private polls", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
options: TWO_OPTIONS, options: TWO_OPTIONS,
pollName: "Two Choice Poll", pollName: "Two Choice Poll",
@ -80,22 +88,28 @@ module("Poll | Component | poll-results-standard", function (hooks) {
fetchVoters: () => {}, fetchVoters: () => {},
}); });
await render(hbs`<PollResultsStandard await render(
@options={{this.options}} <template>
@pollName={{this.pollName}} <PollResultsStandard
@pollType={{this.pollType}} @options={{self.options}}
@isPublic={{this.isPublic}} @pollName={{self.pollName}}
@postId={{this.postId}} @pollType={{self.pollType}}
@vote={{this.vote}} @isPublic={{self.isPublic}}
@voters={{this.voters}} @postId={{self.postId}}
@votersCount={{this.votersCount}} @vote={{self.vote}}
@fetchVoters={{this.fetchVoters}} @voters={{self.voters}}
/>`); @votersCount={{self.votersCount}}
@fetchVoters={{self.fetchVoters}}
/>
</template>
);
assert.dom("ul.poll-voters-list").doesNotExist(); assert.dom("ul.poll-voters-list").doesNotExist();
}); });
test("options in ascending order", async function (assert) { test("options in ascending order", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
options: TWO_OPTIONS_REVERSED, options: TWO_OPTIONS_REVERSED,
pollName: "Two Choice Poll", pollName: "Two Choice Poll",
@ -107,22 +121,28 @@ module("Poll | Component | poll-results-standard", function (hooks) {
fetchVoters: () => {}, fetchVoters: () => {},
}); });
await render(hbs`<PollResultsStandard await render(
@options={{this.options}} <template>
@pollName={{this.pollName}} <PollResultsStandard
@pollType={{this.pollType}} @options={{self.options}}
@postId={{this.postId}} @pollName={{self.pollName}}
@vote={{this.vote}} @pollType={{self.pollType}}
@voters={{this.voters}} @postId={{self.postId}}
@votersCount={{this.votersCount}} @vote={{self.vote}}
@fetchVoters={{this.fetchVoters}} @voters={{self.voters}}
/>`); @votersCount={{self.votersCount}}
@fetchVoters={{self.fetchVoters}}
/>
</template>
);
assert.dom(queryAll(".option .percentage")[0]).hasText("56%"); assert.dom(queryAll(".option .percentage")[0]).hasText("56%");
assert.dom(queryAll(".option .percentage")[1]).hasText("44%"); assert.dom(queryAll(".option .percentage")[1]).hasText("44%");
}); });
test("options in ascending order", async function (assert) { test("options in ascending order", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
options: FIVE_OPTIONS, options: FIVE_OPTIONS,
pollName: "Five Multi Option Poll", pollName: "Five Multi Option Poll",
@ -134,16 +154,20 @@ module("Poll | Component | poll-results-standard", function (hooks) {
fetchVoters: () => {}, fetchVoters: () => {},
}); });
await render(hbs`<PollResultsStandard await render(
@options={{this.options}} <template>
@pollName={{this.pollName}} <PollResultsStandard
@pollType={{this.pollType}} @options={{self.options}}
@postId={{this.postId}} @pollName={{self.pollName}}
@vote={{this.vote}} @pollType={{self.pollType}}
@voters={{this.voters}} @postId={{self.postId}}
@votersCount={{this.votersCount}} @vote={{self.vote}}
@fetchVoters={{this.fetchVoters}} @voters={{self.voters}}
/>`); @votersCount={{self.votersCount}}
@fetchVoters={{self.fetchVoters}}
/>
</template>
);
let percentages = queryAll(".option .percentage"); let percentages = queryAll(".option .percentage");
assert.dom(percentages[0]).hasText("41%"); assert.dom(percentages[0]).hasText("41%");
@ -157,6 +181,8 @@ module("Poll | Component | poll-results-standard", function (hooks) {
}); });
test("options in ascending order, showing absolute vote number", async function (assert) { test("options in ascending order, showing absolute vote number", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
options: FIVE_OPTIONS, options: FIVE_OPTIONS,
pollName: "Five Multi Option Poll", pollName: "Five Multi Option Poll",
@ -169,17 +195,21 @@ module("Poll | Component | poll-results-standard", function (hooks) {
showTally: true, showTally: true,
}); });
await render(hbs`<PollResultsStandard await render(
@options={{this.options}} <template>
@pollName={{this.pollName}} <PollResultsStandard
@pollType={{this.pollType}} @options={{self.options}}
@postId={{this.postId}} @pollName={{self.pollName}}
@vote={{this.vote}} @pollType={{self.pollType}}
@voters={{this.voters}} @postId={{self.postId}}
@votersCount={{this.votersCount}} @vote={{self.vote}}
@fetchVoters={{this.fetchVoters}} @voters={{self.voters}}
@showTally={{this.showTally}} @votersCount={{self.votersCount}}
/>`); @fetchVoters={{self.fetchVoters}}
@showTally={{self.showTally}}
/>
</template>
);
let percentages = queryAll(".option .absolute"); let percentages = queryAll(".option .absolute");
assert.dom(percentages[0]).hasText(i18n("poll.votes", { count: 5 })); assert.dom(percentages[0]).hasText(i18n("poll.votes", { count: 5 }));

View File

@ -1,7 +1,7 @@
import { render } from "@ember/test-helpers"; import { render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import PollResultsTabs from "discourse/plugins/poll/discourse/components/poll-results-tabs";
const TWO_OPTIONS = [ const TWO_OPTIONS = [
{ {
@ -59,6 +59,8 @@ module("Poll | Component | poll-results-tabs", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
test("Renders one tab for non-ranked-choice poll", async function (assert) { test("Renders one tab for non-ranked-choice poll", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
options: TWO_OPTIONS, options: TWO_OPTIONS,
pollName: "Two Choice Poll", pollName: "Two Choice Poll",
@ -72,23 +74,29 @@ module("Poll | Component | poll-results-tabs", function (hooks) {
fetchVoters: () => {}, fetchVoters: () => {},
}); });
await render(hbs`<PollResultsTabs await render(
@options={{this.options}} <template>
@pollName={{this.pollName}} <PollResultsTabs
@pollType={{this.pollType}} @options={{self.options}}
@isPublic={{this.isPublic}} @pollName={{self.pollName}}
@isRankedChoice={{this.isRankedChoice}} @pollType={{self.pollType}}
@postId={{this.postId}} @isPublic={{self.isPublic}}
@vote={{this.vote}} @isRankedChoice={{self.isRankedChoice}}
@voters={{this.voters}} @postId={{self.postId}}
@votersCount={{this.votersCount}} @vote={{self.vote}}
@fetchVoters={{this.fetchVoters}} @voters={{self.voters}}
/>`); @votersCount={{self.votersCount}}
@fetchVoters={{self.fetchVoters}}
/>
</template>
);
assert.dom("li.tab").exists({ count: 1 }); assert.dom("li.tab").exists({ count: 1 });
}); });
test("Renders two tabs for public ranked choice poll", async function (assert) { test("Renders two tabs for public ranked choice poll", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
options: TWO_OPTIONS, options: TWO_OPTIONS,
pollName: "Two Choice Poll", pollName: "Two Choice Poll",
@ -103,24 +111,30 @@ module("Poll | Component | poll-results-tabs", function (hooks) {
fetchVoters: () => {}, fetchVoters: () => {},
}); });
await render(hbs`<PollResultsTabs await render(
@options={{this.options}} <template>
@pollName={{this.pollName}} <PollResultsTabs
@pollType={{this.pollType}} @options={{self.options}}
@isPublic={{this.isPublic}} @pollName={{self.pollName}}
@isRankedChoice={{this.isRankedChoice}} @pollType={{self.pollType}}
@rankedChoiceOutcome={{this.rankedChoiceOutcome}} @isPublic={{self.isPublic}}
@postId={{this.postId}} @isRankedChoice={{self.isRankedChoice}}
@vote={{this.vote}} @rankedChoiceOutcome={{self.rankedChoiceOutcome}}
@voters={{this.voters}} @postId={{self.postId}}
@votersCount={{this.votersCount}} @vote={{self.vote}}
@fetchVoters={{this.fetchVoters}} @voters={{self.voters}}
/>`); @votersCount={{self.votersCount}}
@fetchVoters={{self.fetchVoters}}
/>
</template>
);
assert.dom("li.tab").exists({ count: 2 }); assert.dom("li.tab").exists({ count: 2 });
}); });
test("Renders one tab for private ranked choice poll", async function (assert) { test("Renders one tab for private ranked choice poll", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
options: TWO_OPTIONS, options: TWO_OPTIONS,
pollName: "Two Choice Poll", pollName: "Two Choice Poll",
@ -135,19 +149,23 @@ module("Poll | Component | poll-results-tabs", function (hooks) {
fetchVoters: () => {}, fetchVoters: () => {},
}); });
await render(hbs`<PollResultsTabs await render(
@options={{this.options}} <template>
@pollName={{this.pollName}} <PollResultsTabs
@pollType={{this.pollType}} @options={{self.options}}
@isPublic={{this.isPublic}} @pollName={{self.pollName}}
@isRankedChoice={{this.isRankedChoice}} @pollType={{self.pollType}}
@rankedChoiceOutcome={{this.rankedChoiceOutcome}} @isPublic={{self.isPublic}}
@postId={{this.postId}} @isRankedChoice={{self.isRankedChoice}}
@vote={{this.vote}} @rankedChoiceOutcome={{self.rankedChoiceOutcome}}
@voters={{this.voters}} @postId={{self.postId}}
@votersCount={{this.votersCount}} @vote={{self.vote}}
@fetchVoters={{this.fetchVoters}} @voters={{self.voters}}
/>`); @votersCount={{self.votersCount}}
@fetchVoters={{self.fetchVoters}}
/>
</template>
);
assert.dom("li.tab").exists({ count: 1 }); assert.dom("li.tab").exists({ count: 1 });
}); });

View File

@ -1,11 +1,11 @@
import EmberObject from "@ember/object"; import EmberObject from "@ember/object";
import { click, render } from "@ember/test-helpers"; import { click, render } from "@ember/test-helpers";
import { TrackedObject } from "@ember-compat/tracked-built-ins"; import { TrackedObject } from "@ember-compat/tracked-built-ins";
import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import pretender, { response } from "discourse/tests/helpers/create-pretender"; import pretender, { response } from "discourse/tests/helpers/create-pretender";
import { i18n } from "discourse-i18n"; import { i18n } from "discourse-i18n";
import Poll from "discourse/plugins/poll/discourse/components/poll";
let requests = 0; let requests = 0;
@ -42,6 +42,8 @@ module("Poll | Component | poll", function (hooks) {
}); });
test("valid ranks with which you can vote", async function (assert) { test("valid ranks with which you can vote", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
post: EmberObject.create({ post: EmberObject.create({
id: 42, id: 42,
@ -96,13 +98,17 @@ module("Poll | Component | poll", function (hooks) {
}), }),
}); });
await render(hbs`<Poll @post={{this.post}} @poll={{this.poll}} />`); await render(
<template><Poll @post={{self.post}} @poll={{self.poll}} /></template>
);
assert.dom(".poll-buttons .cast-votes:disabled").doesNotExist(); assert.dom(".poll-buttons .cast-votes:disabled").doesNotExist();
assert.dom(".poll-buttons .cast-votes").exists(); assert.dom(".poll-buttons .cast-votes").exists();
}); });
test("invalid ranks with which you cannot vote", async function (assert) { test("invalid ranks with which you cannot vote", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
post: EmberObject.create({ post: EmberObject.create({
id: 42, id: 42,
@ -141,7 +147,9 @@ module("Poll | Component | poll", function (hooks) {
}), }),
}); });
await render(hbs`<Poll @post={{this.post}} @poll={{this.poll}} />`); await render(
<template><Poll @post={{self.post}} @poll={{self.poll}} /></template>
);
await click( await click(
".ranked-choice-poll-option[data-poll-option-id='1f972d1df351de3ce35a787c89faad29'] button", ".ranked-choice-poll-option[data-poll-option-id='1f972d1df351de3ce35a787c89faad29'] button",
@ -171,6 +179,8 @@ module("Poll | Component | poll", function (hooks) {
}); });
test("shows vote", async function (assert) { test("shows vote", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
post: EmberObject.create({ post: EmberObject.create({
id: 42, id: 42,
@ -193,13 +203,17 @@ module("Poll | Component | poll", function (hooks) {
}), }),
}); });
await render(hbs`<Poll @post={{this.post}} @poll={{this.poll}} />`); await render(
<template><Poll @post={{self.post}} @poll={{self.poll}} /></template>
);
assert.dom(".results li:nth-of-type(1) .option p").hasText("100% yes"); assert.dom(".results li:nth-of-type(1) .option p").hasText("100% yes");
assert.dom(".results li:nth-of-type(2) .option p").hasText("0% no"); assert.dom(".results li:nth-of-type(2) .option p").hasText("0% no");
}); });
test("does not show results after voting when results are to be shown only on closed", async function (assert) { test("does not show results after voting when results are to be shown only on closed", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
post: EmberObject.create({ post: EmberObject.create({
id: 42, id: 42,
@ -222,13 +236,17 @@ module("Poll | Component | poll", function (hooks) {
}), }),
}); });
await render(hbs`<Poll @post={{this.post}} @poll={{this.poll}} />`); await render(
<template><Poll @post={{self.post}} @poll={{self.poll}} /></template>
);
assert.dom("ul.options").exists("options are shown"); assert.dom("ul.options").exists("options are shown");
assert.dom("ul.results").doesNotExist("results are not shown"); assert.dom("ul.results").doesNotExist("results are not shown");
}); });
test("can vote", async function (assert) { test("can vote", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
post: EmberObject.create({ post: EmberObject.create({
id: 42, id: 42,
@ -251,7 +269,9 @@ module("Poll | Component | poll", function (hooks) {
}), }),
}); });
await render(hbs`<Poll @post={{this.post}} @poll={{this.poll}} />`); await render(
<template><Poll @post={{self.post}} @poll={{self.poll}} /></template>
);
requests = 0; requests = 0;
@ -268,6 +288,8 @@ module("Poll | Component | poll", function (hooks) {
}); });
test("cannot vote if not member of the right group", async function (assert) { test("cannot vote if not member of the right group", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
post: EmberObject.create({ post: EmberObject.create({
id: 42, id: 42,
@ -291,7 +313,9 @@ module("Poll | Component | poll", function (hooks) {
}), }),
}); });
await render(hbs`<Poll @post={{this.post}} @poll={{this.poll}} />`); await render(
<template><Poll @post={{self.post}} @poll={{self.poll}} /></template>
);
requests = 0; requests = 0;
@ -306,6 +330,8 @@ module("Poll | Component | poll", function (hooks) {
}); });
test("voting on a multiple poll with no min attribute", async function (assert) { test("voting on a multiple poll with no min attribute", async function (assert) {
const self = this;
this.setProperties({ this.setProperties({
post: EmberObject.create({ post: EmberObject.create({
id: 42, id: 42,
@ -328,7 +354,9 @@ module("Poll | Component | poll", function (hooks) {
chart_type: "bar", chart_type: "bar",
}), }),
}); });
await render(hbs`<Poll @post={{this.post}} @poll={{this.poll}} />`); await render(
<template><Poll @post={{self.post}} @poll={{self.poll}} /></template>
);
assert.dom(".poll-buttons .cast-votes").isDisabled(); assert.dom(".poll-buttons .cast-votes").isDisabled();

View File

@ -1,18 +1,22 @@
import { click, fillIn, render } from "@ember/test-helpers"; import { click, fillIn, render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import PollUiBuilder from "discourse/plugins/poll/discourse/components/modal/poll-ui-builder";
async function setupBuilder(context) { async function setupBuilder() {
const noop = () => {};
const results = []; const results = [];
const model = { const model = {
toolbarEvent: { getText: () => "", addText: (t) => results.push(t) }, toolbarEvent: { getText: () => "", addText: (t) => results.push(t) },
}; };
context.model = model;
await render( await render(
hbs`<Modal::PollUiBuilder @inline={{true}} @model={{this.model}} @closeModal={{fn (mut this.closeCalled) true}} />` <template>
<PollUiBuilder @inline={{true}} @model={{model}} @closeModal={{noop}} />
</template>
); );
return results; return results;
} }
@ -20,7 +24,7 @@ module("Poll | Component | poll-ui-builder", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
test("Can switch poll type", async function (assert) { test("Can switch poll type", async function (assert) {
await setupBuilder(this); await setupBuilder();
assert.dom(".poll-type-value-regular").hasClass("active"); assert.dom(".poll-type-value-regular").hasClass("active");
@ -45,7 +49,7 @@ module("Poll | Component | poll-ui-builder", function (hooks) {
}); });
test("Automatically updates min/max when number of options change", async function (assert) { test("Automatically updates min/max when number of options change", async function (assert) {
await setupBuilder(this); await setupBuilder();
await click(".poll-type-value-multiple"); await click(".poll-type-value-multiple");
assert.dom(".poll-options-min").hasValue("0"); assert.dom(".poll-options-min").hasValue("0");
@ -65,7 +69,7 @@ module("Poll | Component | poll-ui-builder", function (hooks) {
test("disables save button", async function (assert) { test("disables save button", async function (assert) {
this.siteSettings.poll_maximum_options = 3; this.siteSettings.poll_maximum_options = 3;
await setupBuilder(this); await setupBuilder();
assert assert
.dom(".insert-poll") .dom(".insert-poll")
.isDisabled("Insert button disabled when no options specified"); .isDisabled("Insert button disabled when no options specified");
@ -88,7 +92,7 @@ module("Poll | Component | poll-ui-builder", function (hooks) {
}); });
test("number mode", async function (assert) { test("number mode", async function (assert) {
const results = await setupBuilder(this); const results = await setupBuilder();
await click(".show-advanced"); await click(".show-advanced");
await click(".poll-type-value-number"); await click(".poll-type-value-number");
@ -122,7 +126,7 @@ module("Poll | Component | poll-ui-builder", function (hooks) {
}); });
test("regular mode", async function (assert) { test("regular mode", async function (assert) {
const results = await setupBuilder(this); const results = await setupBuilder();
await fillIn(".poll-option-value input", "a"); await fillIn(".poll-option-value input", "a");
await click(".poll-option-add"); await click(".poll-option-add");
@ -160,7 +164,7 @@ module("Poll | Component | poll-ui-builder", function (hooks) {
}); });
test("multi-choice mode", async function (assert) { test("multi-choice mode", async function (assert) {
const results = await setupBuilder(this); const results = await setupBuilder();
await click(".poll-type-value-multiple"); await click(".poll-type-value-multiple");
@ -188,7 +192,7 @@ module("Poll | Component | poll-ui-builder", function (hooks) {
}); });
test("staff_only option is not present for non-staff", async function (assert) { test("staff_only option is not present for non-staff", async function (assert) {
await setupBuilder(this); await setupBuilder();
await click(".show-advanced"); await click(".show-advanced");
const resultVisibility = selectKit(".poll-result"); const resultVisibility = selectKit(".poll-result");
@ -215,7 +219,7 @@ module("Poll | Component | poll-ui-builder", function (hooks) {
test("default public value can be controlled with site setting", async function (assert) { test("default public value can be controlled with site setting", async function (assert) {
this.siteSettings.poll_default_public = false; this.siteSettings.poll_default_public = false;
const results = await setupBuilder(this); const results = await setupBuilder();
await fillIn(".poll-option-value input", "a"); await fillIn(".poll-option-value input", "a");
await click(".poll-option-add"); await click(".poll-option-add");

View File

@ -1,4 +1,7 @@
const ColorExample = <template>
<section class="color-example"> <section class="color-example">
<div class="color-bg {{@color}}"></div> <div class="color-bg {{@color}}"></div>
<div class="color-name">var(--{{@color}})</div> <div class="color-name">var(--{{@color}})</div>
</section> </section>
</template>;
export default ColorExample;

View File

@ -1,3 +1,7 @@
import { i18n } from "discourse-i18n";
import StyleguideExample from "discourse/plugins/styleguide/discourse/components/styleguide-example";
const FontScale = <template>
<div class="section-description"> <div class="section-description">
<p> <p>
Discourse users can select from 4 different text sizes in their user Discourse users can select from 4 different text sizes in their user
@ -11,10 +15,10 @@
</p> </p>
<p> <p>
If you'd like to increase the font size of your entire Discourse community, If you'd like to increase the font size of your entire Discourse
you can override the font-size of the HTML element. You can also provide community, you can override the font-size of the HTML element. You can
different font sizes for the user text size settings defined above. The also provide different font sizes for the user text size settings defined
example below increases all text size options by 1px. above. The example below increases all text size options by 1px.
<pre> <pre>
html { html {
<span <span
@ -38,24 +42,25 @@
</p> </p>
<p> <p>
If you want to scale the fonts of a specific element, you can use If you want to scale the fonts of a specific element, you can use
Discourse's font scaling variables. Using the variable system ensures you're Discourse's font scaling variables. Using the variable system ensures
using a consistent set of font-sizes throughout your community. you're using a consistent set of font-sizes throughout your community.
<p> <p>
Changing the font-size of a parent element will proportionately scale the Changing the font-size of a parent element will proportionately scale
font sizes of all its children. the font sizes of all its children.
</p> </p>
<pre> <pre>
.parent { .parent {
<span <span
class="hljs-attribute" class="hljs-attribute"
>font-size</span>: var(--font-up-3); >font-size</span>: var(--font-up-3);
<span>// Increases the relative <span>// Increases the
font-size of this element and its children by 3 steps in the scale</span> relative font-size of this element and its children by 3 steps in the
scale</span>
.child { .child {
<span <span>// If this is set to
>// If this is set to var(--font-down-3) in Discourse's default CSS, the var(--font-down-3) in Discourse's default CSS, the parent font-size
parent font-size increase above would make this equivalent to increase above would make this equivalent to var(--font-0)
var(--font-0) (var(--font-down-3) + var(--font-up-3) = var(--font-0))</span> (var(--font-down-3) + var(--font-up-3) = var(--font-0))</span>
} } } }
</pre> </pre>
</p> </p>
@ -112,3 +117,5 @@
<StyleguideExample @title="var(--font-down-6), 0.4355em"> <StyleguideExample @title="var(--font-down-6), 0.4355em">
<p class="font-down-6">{{i18n "styleguide.sections.typography.example"}}</p> <p class="font-down-6">{{i18n "styleguide.sections.typography.example"}}</p>
</StyleguideExample> </StyleguideExample>
</template>;
export default FontScale;

View File

@ -1,3 +1,13 @@
import { fn } from "@ember/helper";
import { on } from "@ember/modifier";
import { not } from "truth-helpers";
import DButton from "discourse/components/d-button";
import DToggleSwitch from "discourse/components/d-toggle-switch";
import FlatButton from "discourse/components/flat-button";
import concatClass from "discourse/helpers/concat-class";
import StyleguideExample from "discourse/plugins/styleguide/discourse/components/styleguide-example";
const Buttons = <template>
<StyleguideExample @title=".btn-icon - sizes (large, default, small)"> <StyleguideExample @title=".btn-icon - sizes (large, default, small)">
{{#each @dummy.buttonSizes as |bs|}} {{#each @dummy.buttonSizes as |bs|}}
<DButton <DButton
@ -72,7 +82,7 @@
@icon="plus" @icon="plus"
@translatedLabel={{bs.text}} @translatedLabel={{bs.text}}
@disabled={{bs.disabled}} @disabled={{bs.disabled}}
class={{concat-class "btn-primary" bs.class}} class={{concatClass "btn-primary" bs.class}}
/> />
{{/each}} {{/each}}
</StyleguideExample> </StyleguideExample>
@ -83,7 +93,7 @@
@icon="plus" @icon="plus"
@translatedLabel={{bs.text}} @translatedLabel={{bs.text}}
@disabled={{bs.disabled}} @disabled={{bs.disabled}}
class={{concat-class "btn-primary" bs.class}} class={{concatClass "btn-primary" bs.class}}
/> />
{{/each}} {{/each}}
</StyleguideExample> </StyleguideExample>
@ -96,7 +106,7 @@
@icon="trash-can" @icon="trash-can"
@translatedLabel={{bs.text}} @translatedLabel={{bs.text}}
@disabled={{bs.disabled}} @disabled={{bs.disabled}}
class={{concat-class "btn-danger" bs.class}} class={{concatClass "btn-danger" bs.class}}
/> />
{{/each}} {{/each}}
</StyleguideExample> </StyleguideExample>
@ -107,7 +117,7 @@
@icon="trash-can" @icon="trash-can"
@translatedLabel={{bs.text}} @translatedLabel={{bs.text}}
@disabled={{bs.disabled}} @disabled={{bs.disabled}}
class={{concat-class "btn-danger" bs.class}} class={{concatClass "btn-danger" bs.class}}
/> />
{{/each}} {{/each}}
</StyleguideExample> </StyleguideExample>
@ -139,7 +149,7 @@
<DButton <DButton
@disabled={{bs.disabled}} @disabled={{bs.disabled}}
@translatedLabel={{bs.text}} @translatedLabel={{bs.text}}
class={{concat-class "btn-flat" bs.class}} class={{concatClass "btn-flat" bs.class}}
/> />
{{/each}} {{/each}}
</StyleguideExample> </StyleguideExample>
@ -149,7 +159,7 @@
<DButton <DButton
@disabled={{bs.disabled}} @disabled={{bs.disabled}}
@translatedLabel={{bs.text}} @translatedLabel={{bs.text}}
class={{concat-class "btn-flat" bs.class}} class={{concatClass "btn-flat" bs.class}}
/> />
{{/each}} {{/each}}
</StyleguideExample> </StyleguideExample>
@ -173,3 +183,5 @@
title="Disabled with state=false" title="Disabled with state=false"
/> />
</StyleguideExample> </StyleguideExample>
</template>;
export default Buttons;

View File

@ -1,3 +1,7 @@
import ColorExample from "discourse/plugins/styleguide/discourse/components/color-example";
import StyleguideExample from "discourse/plugins/styleguide/discourse/components/styleguide-example";
const Colors = <template>
<StyleguideExample @title="primary"> <StyleguideExample @title="primary">
<section class="color-row"> <section class="color-row">
<ColorExample @color="primary-very-low" /> <ColorExample @color="primary-very-low" />
@ -118,3 +122,5 @@
<ColorExample @color="header_primary-low" /> <ColorExample @color="header_primary-low" />
</section> </section>
</StyleguideExample> </StyleguideExample>
</template>;
export default Colors;

View File

@ -1,3 +1,8 @@
import { i18n } from "discourse-i18n";
import StyleguideExample from "discourse/plugins/styleguide/discourse/components/styleguide-example";
import StyleguideIcons from "discourse/plugins/styleguide/discourse/components/styleguide-icons";
const Icons = <template>
<div class="section-description"> <div class="section-description">
<p>Discourse uses a free set of SVG icons from Font Awesome (<a <p>Discourse uses a free set of SVG icons from Font Awesome (<a
href="https://fontawesome.com/icons?d=gallery&m=free" href="https://fontawesome.com/icons?d=gallery&m=free"
@ -23,3 +28,5 @@
<StyleguideExample @title="d-icon - all available icons"> <StyleguideExample @title="d-icon - all available icons">
<StyleguideIcons /> <StyleguideIcons />
</StyleguideExample> </StyleguideExample>
</template>;
export default Icons;

View File

@ -1,3 +1,8 @@
import { array, fn, hash } from "@ember/helper";
import Form from "discourse/components/form";
import StyleguideExample from "discourse/plugins/styleguide/discourse/components/styleguide-example";
const Forms = <template>
<h2>Controls</h2> <h2>Controls</h2>
<StyleguideExample @title="Input"> <StyleguideExample @title="Input">
<Form as |form|> <Form as |form|>
@ -80,7 +85,10 @@
<StyleguideExample @title="CheckboxGroup"> <StyleguideExample @title="CheckboxGroup">
<Form as |form|> <Form as |form|>
<form.CheckboxGroup @title="I give explicit permission" as |checkboxGroup|> <form.CheckboxGroup
@title="I give explicit permission"
as |checkboxGroup|
>
<checkboxGroup.Field <checkboxGroup.Field
@title="Use my email for any purpose." @title="Use my email for any purpose."
@name="contract" @name="contract"
@ -272,3 +280,5 @@
</form.Field> </form.Field>
</Form> </Form>
</StyleguideExample> </StyleguideExample>
</template>;
export default Forms;

View File

@ -1,3 +1,6 @@
import StyleguideExample from "discourse/plugins/styleguide/discourse/components/styleguide-example";
const Spinners = <template>
<StyleguideExample @title="spinner - small"> <StyleguideExample @title="spinner - small">
<div class="spinner small"></div> <div class="spinner small"></div>
</StyleguideExample> </StyleguideExample>
@ -5,3 +8,5 @@
<StyleguideExample @title="spinner - regular"> <StyleguideExample @title="spinner - regular">
<div class="spinner"></div> <div class="spinner"></div>
</StyleguideExample> </StyleguideExample>
</template>;
export default Spinners;

Some files were not shown because too many files have changed in this diff Show More