Fix uncorrect translation with text should update the text

This commit is contained in:
Simon Prévost 2023-12-15 10:07:45 -05:00
parent 42a7b4bc93
commit d65ab1cd05
9 changed files with 77 additions and 65 deletions

View File

@ -16,13 +16,14 @@ defmodule Accent.GraphQL.Mutations.Translation do
field :uncorrect_translation, :mutated_translation do
arg(:id, non_null(:id))
arg(:text, non_null(:string))
resolve(translation_authorize(:uncorrect_translation, &TranslationResolver.uncorrect/3))
end
field :update_translation, :mutated_translation do
arg(:id, non_null(:id))
arg(:text, :string)
arg(:text, non_null(:string))
resolve(translation_authorize(:update_translation, &TranslationResolver.update/3))
end

View File

@ -52,9 +52,10 @@ defmodule Accent.GraphQL.Resolvers.Translation do
end
@spec uncorrect(Translation.t(), map(), GraphQLContext.t()) :: translation_operation
def uncorrect(translation, _, info) do
def uncorrect(translation, %{text: text}, info) do
%Context{}
|> Context.assign(:translation, translation)
|> Context.assign(:text, text)
|> Context.assign(:user_id, info.context[:conn].assigns[:current_user].id)
|> TranslationUncorrectConflictBuilder.build()
|> then(&fn -> BasePersister.execute(&1) end)

View File

@ -6,8 +6,9 @@ defmodule Movement.Builders.TranslationUncorrectConflict do
@action "uncorrect_conflict"
def build(%Movement.Context{assigns: %{translation: translation}, operations: operations} = context) do
operation = OperationMapper.map(@action, translation, %{text: nil})
def build(%Movement.Context{assigns: %{translation: translation, text: text}, operations: operations} = context) do
value_type = Movement.Mappers.ValueType.from_translation_new_value(translation, text)
operation = OperationMapper.map(@action, translation, %{text: text, value_type: value_type})
%{context | operations: Enum.concat(operations, [operation])}
end

View File

@ -18,11 +18,12 @@ defmodule Movement.Migration.Conflict do
def call(:uncorrect, operation) do
update_all_dynamic(
operation.translation,
[:text, :text, :boolean],
[:conflicted_text, :value_type, :conflicted],
[:text, :text, :text, :boolean],
[:corrected_text, :conflicted_text, :value_type, :conflicted],
[
operation.previous_translation && operation.previous_translation.conflicted_text,
operation.previous_translation && operation.previous_translation.value_type,
operation.text,
operation.previous_translation && operation.previous_translation.corrected_text,
operation.value_type,
true
]
)

View File

@ -7,6 +7,7 @@ defmodule Movement.Persisters.OperationsUpdateAllDynamic do
@uuid_fragment "SELECT * FROM unnest(?::uuid[], ?::uuid[]) AS t(a, b)"
@text_text_bool_bool_fragment "SELECT * FROM unnest(?::uuid[], ?::text[], ?::text[], ?::boolean[], ?::boolean[]) AS t(a, b, c, d, e)"
@text_text_bool_fragment "SELECT * FROM unnest(?::uuid[], ?::text[], ?::text[], ?::boolean[]) AS t(a, b, c, d)"
@text_text_text_bool_fragment "SELECT * FROM unnest(?::uuid[], ?::text[], ?::text[], ?::text[], ?::boolean[]) AS t(a, b, c, d, e)"
def update({{schema, [:text, :text, :boolean, :boolean], fields}, records}) do
[bind_1, bind_2, bind_3, bind_4] = values_binding(records, fields)
@ -28,7 +29,8 @@ defmodule Movement.Persisters.OperationsUpdateAllDynamic do
{^Enum.at(fields, 0), values_list.b},
{^Enum.at(fields, 1), values_list.c},
{^Enum.at(fields, 2), values_list.d},
{^Enum.at(fields, 3), values_list.e}
{^Enum.at(fields, 3), values_list.e},
updated_at: ^DateTime.utc_now(:second)
]
]
)
@ -47,7 +49,7 @@ defmodule Movement.Persisters.OperationsUpdateAllDynamic do
^bind_1
),
on: values_list.a == entries.id,
update: [set: [{^Enum.at(fields, 0), values_list.b}]]
update: [set: [{^Enum.at(fields, 0), values_list.b}, updated_at: ^DateTime.utc_now(:second)]]
)
)
end
@ -70,7 +72,36 @@ defmodule Movement.Persisters.OperationsUpdateAllDynamic do
set: [
{^Enum.at(fields, 0), values_list.b},
{^Enum.at(fields, 1), values_list.c},
{^Enum.at(fields, 2), values_list.d}
{^Enum.at(fields, 2), values_list.d},
updated_at: ^DateTime.utc_now(:second)
]
]
)
)
end
def update({{schema, [:text, :text, :text, :boolean], fields}, records}) do
[bind_1, bind_2, bind_3, bind_4] = values_binding(records, fields)
update_all(
from(entries in schema,
join:
values_list in fragment(
@text_text_text_bool_fragment,
^ids_binding(records),
^bind_1,
^bind_2,
^bind_3,
^bind_4
),
on: values_list.a == entries.id,
update: [
set: [
{^Enum.at(fields, 0), values_list.b},
{^Enum.at(fields, 1), values_list.c},
{^Enum.at(fields, 2), values_list.d},
{^Enum.at(fields, 3), values_list.e},
updated_at: ^DateTime.utc_now(:second)
]
]
)

View File

@ -11,7 +11,7 @@ interface Args {
onChangeText?: (text: string) => void;
onUpdateText: (text: string) => Promise<void>;
onCorrectConflict: (text: string) => Promise<void>;
onUncorrectConflict: () => Promise<void>;
onUncorrectConflict: (text: string) => Promise<void>;
}
export default class TranslationEdit extends Component<Args> {
@ -92,7 +92,7 @@ export default class TranslationEdit extends Component<Args> {
async uncorrectConflict() {
this.isUncorrectingConflict = true;
await this.args.onUncorrectConflict();
await this.args.onUncorrectConflict(this.text);
this.isUncorrectingConflict = false;
}

View File

@ -33,59 +33,35 @@
{{/if}}
{{#if @translation}}
{{#if @translation.isConflicted}}
{{#unless @translation.isRemoved}}
<div local-class='actions'>
<div local-class='actions-links'>
{{#if @translation.sourceTranslation}}
<LinkTo @route='logged-in.project.translation' @models={{array @project.id @translation.sourceTranslation.id}} local-class='actions-link'>
{{t 'components.translation_edit.source_translation'}}
</LinkTo>
{{/if}}
</div>
<div local-class='actions-buttons'>
{{#unless this.hasTextNotChanged}}
<AsyncButton @onClick={{fn this.setOriginalText}} local-class='actions-button-revert' class='button button--iconOnly button--white'>
{{inline-svg '/assets/revert.svg' class='button-icon'}}
</AsyncButton>
{{/unless}}
{{#unless @translation.isRemoved}}
<div local-class='actions'>
<div local-class='actions-links'>
{{#if @translation.sourceTranslation}}
<LinkTo @route='logged-in.project.translation' @models={{array @project.id @translation.sourceTranslation.id}} local-class='actions-link'>
{{t 'components.translation_edit.source_translation'}}
</LinkTo>
{{/if}}
</div>
<div local-class='actions-buttons'>
{{#unless this.hasTextNotChanged}}
<AsyncButton @onClick={{fn this.setOriginalText}} local-class='actions-button-revert' class='button button--iconOnly button--white'>
{{inline-svg '/assets/revert.svg' class='button-icon'}}
</AsyncButton>
{{/unless}}
{{#if (get @permissions 'update_translation')}}
<AsyncButton @loading={{this.isUpdatingText}} @disabled={{this.hasTextNotChanged}} class='button button--filled button--white' @onClick={{fn this.updateText}}>
{{t 'components.translation_edit.update_text'}}
</AsyncButton>
{{/if}}
{{#if (get @permissions 'update_translation')}}
<AsyncButton @loading={{this.isUpdatingText}} @disabled={{this.hasTextNotChanged}} class='button button--filled button--white' @onClick={{fn this.updateText}}>
{{t 'components.translation_edit.update_text'}}
</AsyncButton>
{{/if}}
{{#if @translation.isConflicted}}
{{#if (get @permissions 'correct_translation')}}
<AsyncButton @loading={{this.isCorrectingConflict}} class='button button--filled' @onClick={{fn this.correctConflict}}>
{{inline-svg '/assets/check.svg' class='button-icon'}}
{{t 'components.translation_edit.correct_button'}}
</AsyncButton>
{{/if}}
</div>
</div>
{{/unless}}
{{else}}
{{#unless @translation.isRemoved}}
<div local-class='actions'>
<div local-class='actions-links'>
{{#if @translation.sourceTranslation}}
<LinkTo @route='logged-in.project.translation' @models={{array @project.id @translation.sourceTranslation.id}} local-class='actions-link'>
{{t 'components.translation_edit.source_translation'}}
</LinkTo>
{{/if}}
</div>
<div local-class='actions-buttons'>
{{#unless this.hasTextNotChanged}}
<AsyncButton @onClick={{fn this.setOriginalText}} local-class='actions-button-revert' class='button button--iconOnly button--white'>
{{inline-svg '/assets/revert.svg' class='button-icon'}}
</AsyncButton>
{{/unless}}
{{#if (get @permissions 'update_translation')}}
<AsyncButton @loading={{this.isUpdatingText}} @disabled={{this.hasTextNotChanged}} class='button button--filled button--white' @onClick={{fn this.updateText}}>
{{t 'components.translation_edit.update_text'}}
</AsyncButton>
{{/if}}
{{else}}
{{#if (get @permissions 'uncorrect_translation')}}
<AsyncButton @loading={{this.isUncorrectingConflict}} class='button button--filled button--red' @onClick={{fn this.uncorrectConflict}}>
@ -93,9 +69,9 @@
{{t 'components.translation_edit.uncorrect_button'}}
</AsyncButton>
{{/if}}
</div>
{{/if}}
</div>
{{/unless}}
{{/if}}
</div>
{{/unless}}
{{/if}}
</div>

View File

@ -65,13 +65,14 @@ export default class IndexController extends Controller {
}
@action
async uncorrectConflict() {
async uncorrectConflict(text: string) {
const conflict = this.model.translation;
const response = await this.apolloMutate.mutate({
mutation: translationUncorrectQuery,
variables: {
translationId: conflict.id,
text,
},
});

View File

@ -1,8 +1,8 @@
import gql from 'graphql-tag';
export default gql`
mutation TranslationUncorrect($translationId: ID!) {
uncorrectTranslation(id: $translationId) {
mutation TranslationUncorrect($translationId: ID!, $text: String!) {
uncorrectTranslation(id: $translationId, text: $text) {
translation {
id
correctedText