mirror of
https://github.com/discourse/discourse.git
synced 2025-08-17 18:04:11 +08:00
FEATURE: Add post language on creating a new post (#33160)
This is a second attempt at: https://github.com/discourse/discourse/pull/33001 We had to [revert the commit](https://github.com/discourse/discourse/pull/33157) because it was performing a site-setting check at boot time, which is prone to issues and not allowed. This PR: - re-introduces the changes in the original PR - a fix by not performing a site-setting check at boot time (verified by: `SKIP_DB_AND_REDIS=1 DISCOURSE_DEV_DB="nonexist" bin/rails runner "puts 'booted'"` locally and should be caught by the new CI check introduced here: https://github.com/discourse/discourse/pull/33158) - adds a fix to the translation editor to not show the original post locale in the dropdown, as well as adding an indicator of what the original post locale is in a small badge in the header: - 
This commit is contained in:
parent
73e9ab1caf
commit
4d380a28e7
21 changed files with 281 additions and 73 deletions
|
@ -1,8 +1,10 @@
|
|||
import Component from "@ember/component";
|
||||
import { hash } from "@ember/helper";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import { service } from "@ember/service";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import PostLanguageSelector from "discourse/components/post-language-selector";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import escape from "discourse/lib/escape";
|
||||
import { iconHTML } from "discourse/lib/icon-library";
|
||||
|
@ -28,6 +30,9 @@ const TITLES = {
|
|||
|
||||
@classNames("composer-action-title")
|
||||
export default class ComposerActionTitle extends Component {
|
||||
@service currentUser;
|
||||
@service siteSettings;
|
||||
|
||||
@alias("model.replyOptions") options;
|
||||
@alias("model.action") action;
|
||||
|
||||
|
@ -64,6 +69,20 @@ export default class ComposerActionTitle extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
get showPostLanguageSelector() {
|
||||
const allowedActions = [CREATE_TOPIC, EDIT, REPLY];
|
||||
if (
|
||||
this.currentUser &&
|
||||
this.siteSettings.experimental_content_localization &&
|
||||
this.currentUser.can_localize_content &&
|
||||
allowedActions.includes(this.model.action)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_formatEditUserPost(userAvatar, userLink, postLink, originalUser) {
|
||||
let editTitle = `
|
||||
<a class="post-link" href="${postLink.href}">${postLink.anchor}</a>
|
||||
|
@ -114,5 +133,12 @@ export default class ComposerActionTitle extends Component {
|
|||
<span class="action-title" role="heading" aria-level="1">
|
||||
{{this.actionTitle}}
|
||||
</span>
|
||||
|
||||
{{#if this.showPostLanguageSelector}}
|
||||
<PostLanguageSelector
|
||||
@composerModel={{this.model}}
|
||||
@selectedLanguage={{this.model.locale}}
|
||||
/>
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ export default class EditCategoryLocalizations extends buildCategoryPanel(
|
|||
@service siteSettings;
|
||||
|
||||
get availableLocales() {
|
||||
return JSON.parse(this.siteSettings.available_locales);
|
||||
return this.siteSettings.available_content_localization_locales;
|
||||
}
|
||||
|
||||
<template>
|
||||
|
|
|
@ -12,21 +12,6 @@ export default class LanguageSwitcher extends Component {
|
|||
@service siteSettings;
|
||||
@service router;
|
||||
|
||||
get localeOptions() {
|
||||
const targetLanguages = (
|
||||
this.siteSettings.experimental_content_localization_supported_locales ||
|
||||
""
|
||||
).split("|");
|
||||
return JSON.parse(this.siteSettings.available_locales)
|
||||
.filter(({ value }) => targetLanguages.includes(value))
|
||||
.map(({ name, value }) => {
|
||||
return {
|
||||
label: name,
|
||||
value,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async changeLocale(locale) {
|
||||
cookie("locale", locale, { path: "/" });
|
||||
|
@ -51,13 +36,16 @@ export default class LanguageSwitcher extends Component {
|
|||
>
|
||||
<:content>
|
||||
<DropdownMenu as |dropdown|>
|
||||
{{#each this.localeOptions as |option|}}
|
||||
{{#each
|
||||
this.siteSettings.available_content_localization_locales
|
||||
as |option|
|
||||
}}
|
||||
<dropdown.item
|
||||
class="locale-options"
|
||||
data-menu-option-id={{option.value}}
|
||||
>
|
||||
<DButton
|
||||
@translatedLabel={{option.label}}
|
||||
@translatedLabel={{option.name}}
|
||||
@action={{fn this.changeLocale option.value}}
|
||||
/>
|
||||
</dropdown.item>
|
||||
|
|
|
@ -27,9 +27,15 @@ export default class PostTranslationsModal extends Component {
|
|||
}
|
||||
|
||||
get originalPostContent() {
|
||||
const originalLocale =
|
||||
this.args.model.post?.locale || this.siteSettings.default_locale;
|
||||
|
||||
return `<div class='d-editor-translation-preview-wrapper'>
|
||||
<span class='d-editor-translation-preview-wrapper__header'>
|
||||
${i18n("composer.translations.original_content")}
|
||||
<span class='d-editor-translation-preview-wrapper__original-locale'>
|
||||
${originalLocale}
|
||||
</span>
|
||||
</span>
|
||||
${this.args.model.post.cooked}
|
||||
</div>`;
|
||||
|
@ -62,14 +68,20 @@ export default class PostTranslationsModal extends Component {
|
|||
|
||||
this.args.closeModal();
|
||||
|
||||
await this.composer.open({
|
||||
const composerOpts = {
|
||||
action: Composer.ADD_TRANSLATION,
|
||||
draftKey: "translation",
|
||||
warningsDisabled: true,
|
||||
hijackPreview: this.originalPostContent,
|
||||
post: this.args.model.post,
|
||||
selectedTranslationLocale: locale.locale,
|
||||
});
|
||||
};
|
||||
|
||||
if (locale?.topic_localization) {
|
||||
composerOpts.topicTitle = locale.topic_localization?.title;
|
||||
}
|
||||
|
||||
await this.composer.open(composerOpts);
|
||||
this.composer.model.set("reply", locale.raw);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { fn } from "@ember/helper";
|
||||
import { action } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import DropdownMenu from "discourse/components/dropdown-menu";
|
||||
import DMenu from "float-kit/components/d-menu";
|
||||
|
||||
export default class PostLanguageSelector extends Component {
|
||||
@service siteSettings;
|
||||
|
||||
@action
|
||||
selectPostLanguage(locale) {
|
||||
this.args.composerModel.locale = locale;
|
||||
this.dMenu.close();
|
||||
}
|
||||
|
||||
@action
|
||||
onRegisterApi(api) {
|
||||
this.dMenu = api;
|
||||
}
|
||||
|
||||
<template>
|
||||
<DMenu
|
||||
@identifier="post-language-selector"
|
||||
@title="Post Language"
|
||||
@icon="globe"
|
||||
@label={{@selectedLanguage}}
|
||||
@modalForMobile={{true}}
|
||||
@onRegisterApi={{this.onRegisterApi}}
|
||||
@class="btn-transparent btn-small post-language-selector"
|
||||
>
|
||||
<:content>
|
||||
<DropdownMenu as |dropdown|>
|
||||
{{#each
|
||||
this.siteSettings.available_content_localization_locales
|
||||
as |locale|
|
||||
}}
|
||||
<dropdown.item
|
||||
class="locale=options"
|
||||
data-menu-option-id={{locale.value}}
|
||||
>
|
||||
<DButton
|
||||
@translatedLabel={{locale.name}}
|
||||
@title={{locale.value}}
|
||||
@action={{fn this.selectPostLanguage locale.value}}
|
||||
/>
|
||||
</dropdown.item>
|
||||
{{/each}}
|
||||
</DropdownMenu>
|
||||
</:content>
|
||||
</DMenu>
|
||||
</template>
|
||||
}
|
|
@ -5,6 +5,8 @@ import { service } from "@ember/service";
|
|||
import DEditor from "discourse/components/d-editor";
|
||||
import TextField from "discourse/components/text-field";
|
||||
import lazyHash from "discourse/helpers/lazy-hash";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import PostLocalization from "discourse/models/post-localization";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import DropdownSelectBox from "select-kit/components/dropdown-select-box";
|
||||
|
||||
|
@ -12,28 +14,27 @@ export default class PostTranslationEditor extends Component {
|
|||
@service composer;
|
||||
@service siteSettings;
|
||||
|
||||
get availableLocales() {
|
||||
const allAvailableLocales = JSON.parse(this.siteSettings.available_locales);
|
||||
const supportedLocales =
|
||||
this.siteSettings.experimental_content_localization_supported_locales.split(
|
||||
"|"
|
||||
async findCurrentLocalization() {
|
||||
try {
|
||||
const { post_localizations } = await PostLocalization.find(
|
||||
this.composer.model.post.id
|
||||
);
|
||||
|
||||
if (!supportedLocales.includes(this.siteSettings.default_locale)) {
|
||||
supportedLocales.push(this.siteSettings.default_locale);
|
||||
return post_localizations.find(
|
||||
(localization) =>
|
||||
localization.locale === this.composer.selectedTranslationLocale
|
||||
);
|
||||
} catch (error) {
|
||||
popupAjaxError(error);
|
||||
}
|
||||
|
||||
const filtered = allAvailableLocales.filter((locale) => {
|
||||
return supportedLocales.includes(locale.value);
|
||||
});
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
findCurrentLocalization() {
|
||||
return this.composer.model.post.post_localizations.find(
|
||||
(localization) =>
|
||||
localization.locale === this.composer.selectedTranslationLocale
|
||||
get availableContentLocalizationLocales() {
|
||||
const originalPostLocale =
|
||||
this.composer.model?.post?.locale || this.siteSettings.default_locale;
|
||||
|
||||
return this.siteSettings.available_content_localization_locales.filter(
|
||||
(locale) => locale.value !== originalPostLocale
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -43,13 +44,25 @@ export default class PostTranslationEditor extends Component {
|
|||
}
|
||||
|
||||
@action
|
||||
updateSelectedLocale(locale) {
|
||||
async updateSelectedLocale(locale) {
|
||||
this.composer.selectedTranslationLocale = locale;
|
||||
|
||||
const currentLocalization = this.findCurrentLocalization();
|
||||
const currentLocalization = await this.findCurrentLocalization();
|
||||
|
||||
if (currentLocalization) {
|
||||
this.composer.model.set("reply", currentLocalization.raw);
|
||||
|
||||
if (currentLocalization?.topic_localization) {
|
||||
this.composer.model.set(
|
||||
"title",
|
||||
currentLocalization.topic_localization.title
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.composer.model.setProperties({
|
||||
reply: "",
|
||||
title: "",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +72,7 @@ export default class PostTranslationEditor extends Component {
|
|||
@nameProperty="name"
|
||||
@valueProperty="value"
|
||||
@value={{this.composer.selectedTranslationLocale}}
|
||||
@content={{this.availableLocales}}
|
||||
@content={{this.availableContentLocalizationLocales}}
|
||||
@onChange={{this.updateSelectedLocale}}
|
||||
@options={{hash
|
||||
icon="globe"
|
||||
|
|
|
@ -19,9 +19,15 @@ export default class PostMenuAddTranslationButton extends Component {
|
|||
@tracked showComposer = false;
|
||||
|
||||
get originalPostContent() {
|
||||
const originalLocale =
|
||||
this.args.post?.locale || this.siteSettings.default_locale;
|
||||
|
||||
return `<div class='d-editor-translation-preview-wrapper'>
|
||||
<span class='d-editor-translation-preview-wrapper__header'>
|
||||
${i18n("composer.translations.original_content")}
|
||||
<span class='d-editor-translation-preview-wrapper__original-locale'>
|
||||
${originalLocale}
|
||||
</span>
|
||||
</span>
|
||||
${this.args.post.cooked}
|
||||
</div>`;
|
||||
|
|
|
@ -73,11 +73,13 @@ const CLOSED = "closed",
|
|||
shared_draft: "sharedDraft",
|
||||
no_bump: "noBump",
|
||||
draft_key: "draftKey",
|
||||
locale: "locale",
|
||||
},
|
||||
_update_serializer = {
|
||||
raw: "reply",
|
||||
topic_id: "topic.id",
|
||||
original_text: "originalText",
|
||||
locale: "locale",
|
||||
},
|
||||
_edit_topic_serializer = {
|
||||
title: "topic.title",
|
||||
|
@ -86,6 +88,7 @@ const CLOSED = "closed",
|
|||
featuredLink: "topic.featured_link",
|
||||
original_title: "originalTitle",
|
||||
original_tags: "originalTags",
|
||||
locale: "locale",
|
||||
},
|
||||
_draft_serializer = {
|
||||
reply: "reply",
|
||||
|
@ -103,6 +106,7 @@ const CLOSED = "closed",
|
|||
original_text: "originalText",
|
||||
original_title: "originalTitle",
|
||||
original_tags: "originalTags",
|
||||
locale: "locale",
|
||||
},
|
||||
_add_draft_fields = {},
|
||||
FAST_REPLY_LENGTH_THRESHOLD = 10000;
|
||||
|
@ -114,6 +118,7 @@ export const SAVE_LABELS = {
|
|||
[PRIVATE_MESSAGE]: "composer.create_pm",
|
||||
[CREATE_SHARED_DRAFT]: "composer.create_shared_draft",
|
||||
[EDIT_SHARED_DRAFT]: "composer.save_edit",
|
||||
[ADD_TRANSLATION]: "composer.translations.save",
|
||||
};
|
||||
|
||||
export const SAVE_ICONS = {
|
||||
|
@ -204,6 +209,7 @@ export default class Composer extends RestModel {
|
|||
@tracked post;
|
||||
@tracked reply;
|
||||
@tracked whisper;
|
||||
@tracked locale = this.post?.locale || this.siteSettings.default_locale;
|
||||
|
||||
unlistTopic = false;
|
||||
noBump = false;
|
||||
|
@ -1176,6 +1182,7 @@ export default class Composer extends RestModel {
|
|||
typingTime: this.typingTime,
|
||||
composerTime: this.composerTime,
|
||||
metaData: this.metaData,
|
||||
locale: this.locale,
|
||||
});
|
||||
|
||||
this.serialize(_create_serializer, createdPost);
|
||||
|
|
|
@ -367,8 +367,6 @@ export default class ComposerService extends Service {
|
|||
return "composer.create_whisper";
|
||||
} else if (privateMessage && modelAction === Composer.REPLY) {
|
||||
return "composer.create_pm";
|
||||
} else if (modelAction === Composer.ADD_TRANSLATION) {
|
||||
return "composer.translations.save";
|
||||
}
|
||||
|
||||
return SAVE_LABELS[modelAction];
|
||||
|
@ -1476,6 +1474,7 @@ export default class ComposerService extends Service {
|
|||
action: CREATE_TOPIC,
|
||||
draftKey: this.topicDraftKey,
|
||||
draftSequence: 0,
|
||||
locale: this.siteSettings.default_locale,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1518,6 +1517,8 @@ export default class ComposerService extends Service {
|
|||
isWarning: false,
|
||||
hasTargetGroups: opts.hasGroups,
|
||||
warningsDisabled: opts.warningsDisabled,
|
||||
locale:
|
||||
opts?.locale || opts?.post?.locale || this.siteSettings.default_locale,
|
||||
});
|
||||
|
||||
if (!this.model.targetRecipients) {
|
||||
|
|
|
@ -9,3 +9,15 @@
|
|||
color: var(--quaternary);
|
||||
}
|
||||
}
|
||||
|
||||
.post-language-selector-content {
|
||||
z-index: z("composer", "dropdown");
|
||||
}
|
||||
|
||||
.post-language-selector-trigger {
|
||||
margin-left: 1rem;
|
||||
|
||||
.d-button-label {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -420,5 +420,14 @@
|
|||
font-size: var(--font-down-1-rem);
|
||||
color: var(--primary-high);
|
||||
}
|
||||
|
||||
&__original-locale {
|
||||
margin-left: 0.5rem;
|
||||
text-transform: uppercase;
|
||||
font-size: var(--font-down-2);
|
||||
background: var(--tertiary-low);
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: var(--d-border-radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,20 +6,33 @@ class PostLocalizationsController < ApplicationController
|
|||
def show
|
||||
guardian.ensure_can_localize_content!
|
||||
|
||||
params.require(%i[post_id])
|
||||
localizations = PostLocalization.where(post_id: params[:post_id])
|
||||
params.require(:post_id)
|
||||
|
||||
if localizations
|
||||
render json:
|
||||
post = Post.find_by(id: params[:post_id])
|
||||
return render json_error(I18n.t("not_found"), status: :not_found) if post.blank?
|
||||
|
||||
post_localizations = PostLocalization.where(post_id: post.id)
|
||||
|
||||
topic_localizations_by_locale = {}
|
||||
if post.is_first_post?
|
||||
TopicLocalization
|
||||
.where(topic_id: post.topic_id)
|
||||
.each { |tl| topic_localizations_by_locale[tl.locale] = tl }
|
||||
end
|
||||
|
||||
post_localizations.each do |pl|
|
||||
pl.define_singleton_method(:topic_localization) { topic_localizations_by_locale[pl.locale] }
|
||||
end
|
||||
|
||||
render json: {
|
||||
post_localizations:
|
||||
ActiveModel::ArraySerializer.new(
|
||||
localizations,
|
||||
post_localizations,
|
||||
each_serializer: PostLocalizationSerializer,
|
||||
root: false,
|
||||
).as_json,
|
||||
status: :ok
|
||||
else
|
||||
render json_error I18n.t("not_found"), status: :not_found
|
||||
end
|
||||
},
|
||||
status: :ok
|
||||
end
|
||||
|
||||
def create_or_update
|
||||
|
|
|
@ -244,7 +244,11 @@ class PostsController < ApplicationController
|
|||
|
||||
guardian.ensure_can_edit!(post)
|
||||
|
||||
changes = { raw: params[:post][:raw], edit_reason: params[:post][:edit_reason] }
|
||||
changes = {
|
||||
raw: params[:post][:raw],
|
||||
edit_reason: params[:post][:edit_reason],
|
||||
locale: params[:post][:locale],
|
||||
}
|
||||
|
||||
Post.plugin_permitted_update_params.keys.each { |param| changes[param] = params[:post][param] }
|
||||
|
||||
|
@ -853,6 +857,7 @@ class PostsController < ApplicationController
|
|||
visible
|
||||
draft_key
|
||||
composer_version
|
||||
locale
|
||||
]
|
||||
|
||||
Post.plugin_permitted_create_params.each do |key, value|
|
||||
|
|
|
@ -115,6 +115,20 @@ class SiteSetting < ActiveRecord::Base
|
|||
LocaleSiteSetting.values.to_json
|
||||
end
|
||||
|
||||
client_settings << :available_content_localization_locales
|
||||
|
||||
def self.available_content_localization_locales
|
||||
return [] if !SiteSetting.experimental_content_localization?
|
||||
|
||||
supported_locales = SiteSetting.experimental_content_localization_supported_locales.split("|")
|
||||
default_locale = SiteSetting.default_locale
|
||||
if default_locale.present? && !supported_locales.include?(default_locale)
|
||||
supported_locales << default_locale
|
||||
end
|
||||
|
||||
LocaleSiteSetting.values.select { |locale| supported_locales.include?(locale[:value]) }
|
||||
end
|
||||
|
||||
def self.topic_title_length
|
||||
min_topic_title_length..max_topic_title_length
|
||||
end
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PostLocalizationSerializer < ApplicationSerializer
|
||||
attributes :id, :post_id, :locale, :raw
|
||||
attributes :id, :post_id, :post_version, :locale, :raw, :topic_localization
|
||||
|
||||
def topic_localization
|
||||
TopicLocalizationSerializer.new(object.topic_localization, root: false).as_json
|
||||
end
|
||||
|
||||
def include_topic_localization?
|
||||
object.respond_to?(:topic_localization) && object.topic_localization.present?
|
||||
end
|
||||
end
|
||||
|
|
5
app/serializers/topic_localization_serializer.rb
Normal file
5
app/serializers/topic_localization_serializer.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TopicLocalizationSerializer < ApplicationSerializer
|
||||
attributes :id, :topic_id, :locale, :title, :fancy_title
|
||||
end
|
|
@ -555,6 +555,7 @@ class PostCreator
|
|||
via_email
|
||||
raw_email
|
||||
action_code
|
||||
locale
|
||||
].each { |a| post.public_send("#{a}=", @opts[a]) if @opts[a].present? }
|
||||
|
||||
post.extract_quoted_post_numbers
|
||||
|
|
|
@ -40,7 +40,7 @@ class PostRevisor
|
|||
end
|
||||
end
|
||||
|
||||
POST_TRACKED_FIELDS = %w[raw cooked edit_reason user_id wiki post_type]
|
||||
POST_TRACKED_FIELDS = %w[raw cooked edit_reason user_id wiki post_type locale]
|
||||
|
||||
attr_reader :category_changed, :post_revision
|
||||
|
||||
|
|
|
@ -14,13 +14,14 @@ RSpec.describe "Anonymous user language switcher", type: :system do
|
|||
end
|
||||
|
||||
before do
|
||||
SiteSetting.default_locale = "en"
|
||||
SiteSetting.experimental_content_localization_supported_locales = "es|ja"
|
||||
SiteSetting.experimental_content_localization = true
|
||||
SiteSetting.allow_user_locale = true
|
||||
SiteSetting.set_locale_from_cookie = true
|
||||
end
|
||||
|
||||
it "only shows the language switcher based on what is in target languages" do
|
||||
SiteSetting.experimental_content_localization_supported_locales = "es|ja"
|
||||
|
||||
SiteSetting.experimental_anon_language_switcher = false
|
||||
visit("/")
|
||||
|
||||
|
@ -30,6 +31,7 @@ RSpec.describe "Anonymous user language switcher", type: :system do
|
|||
visit("/")
|
||||
|
||||
switcher.expand
|
||||
expect(switcher).to have_content("English (US)")
|
||||
expect(switcher).to have_content("日本語")
|
||||
expect(switcher).to have_content("Español")
|
||||
|
||||
|
|
|
@ -20,7 +20,16 @@ describe "Edit Category Localizations", type: :system do
|
|||
end
|
||||
|
||||
context "when content localization setting is enabled" do
|
||||
before { SiteSetting.experimental_content_localization = true }
|
||||
before do
|
||||
SiteSetting.default_locale = "en"
|
||||
SiteSetting.experimental_content_localization = true
|
||||
SiteSetting.experimental_content_localization_supported_locales = "es|fr"
|
||||
SiteSetting.experimental_content_localization_allowed_groups = Group::AUTO_GROUPS[:everyone]
|
||||
|
||||
if SiteSetting.client_settings.exclude?(:available_content_localization_locales)
|
||||
SiteSetting.client_settings << :available_content_localization_locales
|
||||
end
|
||||
end
|
||||
|
||||
it "should show the localization tab" do
|
||||
category_page.visit_settings(category)
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe "Post translations", type: :system do
|
||||
fab!(:user)
|
||||
POST_LANGUAGE_SWITCHER_SELECTOR = "button[data-identifier='post-language-selector']"
|
||||
|
||||
fab!(:admin)
|
||||
fab!(:topic)
|
||||
fab!(:post) { Fabricate(:post, topic: topic, user: user) }
|
||||
fab!(:post) { Fabricate(:post, topic: topic, user: admin) }
|
||||
let(:topic_page) { PageObjects::Pages::Topic.new }
|
||||
let(:composer) { PageObjects::Components::Composer.new }
|
||||
let(:translation_selector) do
|
||||
PageObjects::Components::SelectKit.new(".translation-selector-dropdown")
|
||||
end
|
||||
let(:post_language_selector) do
|
||||
PageObjects::Components::DMenu.new(POST_LANGUAGE_SWITCHER_SELECTOR)
|
||||
end
|
||||
let(:view_translations_modal) { PageObjects::Modals::ViewTranslationsModal.new }
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
SiteSetting.experimental_content_localization_supported_locales = "en|fr|es|pt_BR"
|
||||
sign_in(admin)
|
||||
SiteSetting.default_locale = "en"
|
||||
SiteSetting.experimental_content_localization_supported_locales = "fr|es|pt_BR"
|
||||
SiteSetting.experimental_content_localization = true
|
||||
SiteSetting.experimental_content_localization_allowed_groups = Group::AUTO_GROUPS[:everyone]
|
||||
SiteSetting.post_menu =
|
||||
|
@ -25,23 +31,13 @@ describe "Post translations", type: :system do
|
|||
topic_page.visit_topic(topic)
|
||||
find("#post_#{post.post_number} .post-action-menu__add-translation").click
|
||||
translation_selector.expand
|
||||
expect(all(".translation-selector-dropdown .select-kit-collection li").count).to eq(4)
|
||||
expect(translation_selector).to have_option_value("en")
|
||||
expect(all(".translation-selector-dropdown .select-kit-collection li").count).to eq(3)
|
||||
expect(translation_selector).to have_option_value("fr")
|
||||
expect(translation_selector).to have_option_value("es")
|
||||
expect(translation_selector).to have_option_value("pt_BR")
|
||||
expect(translation_selector).to have_no_option_value("de")
|
||||
end
|
||||
|
||||
it "always includes the site's default locale in the list of available languages" do
|
||||
SiteSetting.default_locale = "de"
|
||||
topic_page.visit_topic(topic)
|
||||
find("#post_#{post.post_number} .post-action-menu__add-translation").click
|
||||
translation_selector.expand
|
||||
expect(all(".translation-selector-dropdown .select-kit-collection li").count).to eq(5)
|
||||
expect(translation_selector).to have_option_value("de")
|
||||
end
|
||||
|
||||
it "allows a user to translate a post" do
|
||||
topic_page.visit_topic(topic)
|
||||
find("#post_#{post.post_number} .post-action-menu__add-translation").click
|
||||
|
@ -75,7 +71,7 @@ describe "Post translations", type: :system do
|
|||
|
||||
it "allows a user to add a new translation" do
|
||||
topic_page.visit_topic(topic)
|
||||
find("#post_#{post.post_number} .post-action-menu-edit-translations-trigger").click
|
||||
find("#post_1 .post-action-menu-edit-translations-trigger").click
|
||||
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
||||
expect(composer).to be_opened
|
||||
translation_selector.expand
|
||||
|
@ -153,4 +149,31 @@ describe "Post translations", type: :system do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when creating a new post in a different locale" do
|
||||
it "should only show the languages listed in the site setting and default locale" do
|
||||
visit("/latest")
|
||||
page.find("#create-topic").click
|
||||
post_language_selector.expand
|
||||
expect(post_language_selector).to have_content("English (US)") # default locale
|
||||
expect(post_language_selector).to have_content("Français")
|
||||
expect(post_language_selector).to have_content("Español")
|
||||
expect(post_language_selector).to have_content("Português (BR)")
|
||||
end
|
||||
|
||||
it "should allow a user to create a post in a different locale" do
|
||||
visit("/latest")
|
||||
page.find("#create-topic").click
|
||||
post_language_selector.expand
|
||||
post_language_selector.option(".dropdown-menu__item[data-menu-option-id='fr']").click
|
||||
composer.fill_title("Ceci est un sujet de test 1")
|
||||
composer.fill_content("Bonjour le monde")
|
||||
composer.submit
|
||||
|
||||
try_until_success do
|
||||
updated_post = Topic.last.posts.first
|
||||
expect(updated_post.locale).to eq("fr")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue