mirror of
https://github.com/mirego/accent.git
synced 2024-08-17 06:50:31 +03:00
Add fix message replacement in translation form and lint page
This commit is contained in:
parent
c0c8d83c54
commit
4079f5a01b
@ -4,7 +4,6 @@ defmodule AccentTest.ExportController do
|
||||
alias Accent.Document
|
||||
alias Accent.Language
|
||||
alias Accent.Project
|
||||
alias Accent.Repo
|
||||
alias Accent.Revision
|
||||
alias Accent.Translation
|
||||
alias Accent.User
|
||||
@ -308,6 +307,8 @@ defmodule AccentTest.ExportController do
|
||||
end
|
||||
|
||||
if Langue.Formatter.Rails.enabled?() do
|
||||
alias Accent.Repo
|
||||
|
||||
test "export with language overrides", %{conn: conn, project: project, revision: revision} do
|
||||
revision = Repo.update!(Ecto.Changeset.change(revision, %{slug: "testtest"}))
|
||||
document = Factory.insert(Document, project_id: project.id, path: "test2", format: "rails_yml")
|
||||
|
@ -4,7 +4,6 @@ defmodule AccentTest.ExportJIPTController do
|
||||
alias Accent.Document
|
||||
alias Accent.Language
|
||||
alias Accent.Project
|
||||
alias Accent.Repo
|
||||
alias Accent.Revision
|
||||
alias Accent.Translation
|
||||
alias Accent.User
|
||||
@ -125,6 +124,8 @@ defmodule AccentTest.ExportJIPTController do
|
||||
end
|
||||
|
||||
if Langue.Formatter.Rails.enabled?() do
|
||||
alias Accent.Repo
|
||||
|
||||
test "export with language overrides", %{conn: conn, project: project, revision: revision, language: language} do
|
||||
revision = Repo.update!(Ecto.Changeset.change(revision, %{slug: "testtest"}))
|
||||
document = Factory.insert(Document, project_id: project.id, path: "test2", format: "rails_yml")
|
||||
|
@ -1,4 +1,9 @@
|
||||
import {inject as service} from '@ember/service';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
import Component from '@glimmer/component';
|
||||
import {restartableTask} from 'ember-concurrency';
|
||||
import translationUpdateQuery from 'accent-webapp/queries/update-translation';
|
||||
import Apollo from 'accent-webapp/services/apollo';
|
||||
|
||||
interface Args {
|
||||
project: any;
|
||||
@ -12,6 +17,12 @@ interface Stat {
|
||||
}
|
||||
|
||||
export default class LintTranslationsPage extends Component<Args> {
|
||||
@service('apollo')
|
||||
apollo: Apollo;
|
||||
|
||||
@tracked
|
||||
fixLintMessageRunningTranslationId: string | null = null;
|
||||
|
||||
get lintTranslationsStatsCount() {
|
||||
return this.lintTranslationsStats.reduce(
|
||||
(total, stat) => stat.count + total,
|
||||
@ -37,4 +48,21 @@ export default class LintTranslationsPage extends Component<Args> {
|
||||
count
|
||||
})) as Stat[];
|
||||
}
|
||||
|
||||
fixLintMessageTask = restartableTask(
|
||||
async (translation: {id: string}, message: any) => {
|
||||
this.fixLintMessageRunningTranslationId = translation.id;
|
||||
|
||||
await this.apollo.client.mutate({
|
||||
mutation: translationUpdateQuery,
|
||||
refetchQueries: ['Lint'],
|
||||
variables: {
|
||||
text: message.replacement.value,
|
||||
translationId: translation.id
|
||||
}
|
||||
});
|
||||
|
||||
this.fixLintMessageRunningTranslationId = null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import parsedKeyProperty from 'accent-webapp/computed-macros/parsed-key';
|
||||
interface Args {
|
||||
lintTranslation: any;
|
||||
project: any;
|
||||
fix?: (lintTranslation: any, message: any) => void;
|
||||
}
|
||||
|
||||
const escape = document.createElement('textarea');
|
||||
@ -15,6 +16,14 @@ const escapeHTML = (html: string): string => {
|
||||
export default class LintTranslationsPageItem extends Component<Args> {
|
||||
translationKey = parsedKeyProperty(this.args.lintTranslation.translation.key);
|
||||
|
||||
get allReplacable() {
|
||||
return this.args.lintTranslation.messages.every(
|
||||
(message: {replacement: object | null}) => {
|
||||
return Boolean(message.replacement);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get messages() {
|
||||
const mapSet = new Set();
|
||||
return this.args.lintTranslation.messages.flatMap((message: any) => {
|
||||
|
@ -26,6 +26,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.button--iconOnly) {
|
||||
.label {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
&:global(.button--small) {
|
||||
&.button--loading {
|
||||
.loading {
|
||||
|
@ -23,6 +23,12 @@
|
||||
|
||||
.item {
|
||||
margin-bottom: 20px;
|
||||
transition: 0.2s ease-in-out;
|
||||
transition-property: opacity;
|
||||
}
|
||||
|
||||
.item--fixing {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.icon-warning {
|
||||
@ -46,10 +52,9 @@
|
||||
.stats-item {
|
||||
display: inline-flex;
|
||||
gap: 4px;
|
||||
padding: 2px 12px;
|
||||
padding: 4px 12px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid var(--background-light-highlight);
|
||||
background: var(--background-light);
|
||||
background: var(--background-light-highlight);
|
||||
color: var(--text-color-normal);
|
||||
font-size: 12px;
|
||||
cursor: default;
|
||||
|
@ -13,11 +13,26 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.messages-item {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: var(--color-error);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.button-fix {
|
||||
width: max-content;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
--button-text-hover-color: var(--color-green);
|
||||
}
|
||||
}
|
||||
|
||||
.item-language {
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
@ -94,6 +109,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
.item-diff-text {
|
||||
font-size: 13px;
|
||||
color: var(--text-color-normal);
|
||||
|
||||
> div {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.item-text {
|
||||
strong {
|
||||
color: var(--color-green);
|
||||
|
@ -187,3 +187,12 @@
|
||||
margin-right: 6px;
|
||||
stroke: var(--color-black);
|
||||
}
|
||||
|
||||
.lint-messages {
|
||||
transition: 0.2s ease-in-out;
|
||||
transition-property: opacity;
|
||||
}
|
||||
|
||||
.lint-messages--loading {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
@ -76,6 +76,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
.button--blue {
|
||||
--button-text-color: var(--color-blue);
|
||||
}
|
||||
|
||||
.button--green {
|
||||
--button-text-color: var(--color-green);
|
||||
}
|
||||
|
||||
.button--grey {
|
||||
--button-text-color: var(--color-grey);
|
||||
}
|
||||
|
||||
.button--grey,
|
||||
.button--success,
|
||||
.button--black,
|
||||
|
@ -15,8 +15,8 @@
|
||||
</div>
|
||||
|
||||
{{#each @lintTranslations key='id' as |lintTranslation|}}
|
||||
<div local-class='item'>
|
||||
<LintTranslationsPage::Item @project={{@project}} @lintTranslation={{lintTranslation}} />
|
||||
<div local-class='item {{if (eq this.fixLintMessageRunningTranslationId lintTranslation.translation.id) "item--fixing"}}'>
|
||||
<LintTranslationsPage::Item @project={{@project}} @lintTranslation={{lintTranslation}} @fixText={{perform this.fixLintMessageTask}} />
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
@ -2,13 +2,15 @@
|
||||
<div local-class='wrapper' class='lint-translations-item'>
|
||||
<ul local-class='messages'>
|
||||
{{#each this.messages as |message|}}
|
||||
<span local-class='description'>
|
||||
{{#if message.message}}
|
||||
{{message.message}}
|
||||
{{else}}
|
||||
{{t (concat 'components.translation_edit.lint_message.checks.' message.check)}}
|
||||
{{/if}}
|
||||
</span>
|
||||
<li local-class='messages-item'>
|
||||
<span local-class='description'>
|
||||
{{#if message.message}}
|
||||
{{message.message}}
|
||||
{{else}}
|
||||
{{t (concat 'components.translation_edit.lint_message.checks.' message.check)}}
|
||||
{{/if}}
|
||||
</span>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
@ -29,6 +31,32 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div local-class='item-text'>{{{this.annotatedText}}}</div>
|
||||
{{#if this.allReplacable}}
|
||||
<ul>
|
||||
{{#each this.messages as |message|}}
|
||||
{{#if message.replacement}}
|
||||
<li local-class='item-diff-text'>
|
||||
<div>
|
||||
{{string-diff message.replacement.value message.text}}
|
||||
</div>
|
||||
|
||||
{{#if @changeText}}
|
||||
<button {{on 'click' (fn @changeText message.replacement.value)}} class='button button--iconOnly button--borderless button--grey' local-class='button-fix'>
|
||||
{{inline-svg '/assets/arrow-right.svg' class='button-icon'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if @fixText}}
|
||||
<button {{on 'click' (fn @fixText @lintTranslation.translation message)}} class='button button--iconOnly button--borderless button--green' local-class='button-fix'>
|
||||
{{inline-svg '/assets/check.svg' class='button-icon'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<div local-class='item-text'>{{{this.annotatedText}}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
@ -115,5 +115,7 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<LintTranslationsPage::Item @lintTranslation={{this.lintTranslation}} />
|
||||
<div local-class='lint-messages {{if this.fetchLintMessagesTask.isRunning "lint-messages--loading"}}'>
|
||||
<LintTranslationsPage::Item @lintTranslation={{this.lintTranslation}} @changeText={{fn @onKeyUp}} />
|
||||
</div>
|
||||
</div>
|
12
webapp/public/assets/arrow-right.svg
Normal file
12
webapp/public/assets/arrow-right.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
class="feather feather-arrow-right"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M5 12h14M12 5l7 7-7 7" />
|
||||
</svg>
|
After Width: | Height: | Size: 256 B |
12
webapp/public/assets/arrow-up.svg
Normal file
12
webapp/public/assets/arrow-up.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
class="feather feather-arrow-up"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M12 19V5M5 12l7-7 7 7" />
|
||||
</svg>
|
After Width: | Height: | Size: 253 B |
13
webapp/public/assets/check-circle.svg
Normal file
13
webapp/public/assets/check-circle.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
class="feather feather-check-circle"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
|
||||
<path d="M22 4 12 14.01l-3-3" />
|
||||
</svg>
|
After Width: | Height: | Size: 305 B |
13
webapp/public/assets/check-square.svg
Normal file
13
webapp/public/assets/check-square.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
class="feather feather-check-square"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="m9 11 3 3L22 4" />
|
||||
<path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11" />
|
||||
</svg>
|
After Width: | Height: | Size: 323 B |
Loading…
Reference in New Issue
Block a user