mirror of
https://github.com/mirego/accent.git
synced 2024-09-11 10:55:28 +03:00
Add revision deleter in worker to use infinite repo transaction timeout
This commit is contained in:
parent
cd256fa7f5
commit
21d7e42766
@ -37,7 +37,7 @@ config :accent, hook_github_file_server: Accent.Hook.Inbounds.GitHub.FileServer.
|
||||
|
||||
config :accent, Oban,
|
||||
plugins: [Oban.Plugins.Pruner],
|
||||
queues: [hook: 10],
|
||||
queues: [hook: 10, operations: 10],
|
||||
repo: Accent.Repo
|
||||
|
||||
config :absinthe, :schema, Accent.GraphQL.Schema
|
||||
|
13
lib/accent/revisions/delete_worker.ex
Normal file
13
lib/accent/revisions/delete_worker.ex
Normal file
@ -0,0 +1,13 @@
|
||||
defmodule Accent.Revisions.DeleteWorker do
|
||||
use Oban.Worker, queue: :operations
|
||||
|
||||
alias Accent.Repo
|
||||
|
||||
@impl Oban.Worker
|
||||
def perform(%Oban.Job{args: args}) do
|
||||
revision = Repo.get!(Accent.Revision, args["revision_id"])
|
||||
Repo.transaction(fn -> Repo.delete(revision) end, timeout: :infinity)
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
@ -1,6 +1,5 @@
|
||||
defmodule Accent.RevisionManager do
|
||||
alias Accent.Repo
|
||||
alias Ecto.Multi
|
||||
|
||||
import Ecto.Changeset
|
||||
import Ecto.Query
|
||||
@ -21,14 +20,12 @@ defmodule Accent.RevisionManager do
|
||||
end
|
||||
|
||||
def delete(revision) do
|
||||
translations = Ecto.assoc(revision, :translations)
|
||||
operations = Ecto.assoc(revision, :operations)
|
||||
|
||||
Multi.new()
|
||||
|> Multi.delete_all(:operations, operations)
|
||||
|> Multi.delete_all(:translations, translations)
|
||||
|> Multi.delete(:revision, revision)
|
||||
|> Repo.transaction()
|
||||
with {:ok, revision} <- Repo.update(change(revision, marked_as_deleted: true)) do
|
||||
Oban.insert(Accent.Revisions.DeleteWorker.new(%{revision_id: revision.id}))
|
||||
{:ok, %{revision: revision}}
|
||||
else
|
||||
_ -> {:error, nil}
|
||||
end
|
||||
end
|
||||
|
||||
def promote(revision = %{master: true}) do
|
||||
|
@ -22,6 +22,8 @@ defmodule Accent.Revision do
|
||||
has_many(:translations, Accent.Translation)
|
||||
has_many(:operations, Accent.Operation)
|
||||
|
||||
field(:marked_as_deleted, :boolean)
|
||||
|
||||
field(:translations_count, :any, virtual: true, default: :not_loaded)
|
||||
field(:reviewed_count, :any, virtual: true, default: :not_loaded)
|
||||
field(:conflicts_count, :any, virtual: true, default: :not_loaded)
|
||||
|
@ -16,6 +16,7 @@ defmodule Accent.GraphQL.Types.Revision do
|
||||
field(:name, :string)
|
||||
field(:slug, :string)
|
||||
field(:rtl, :boolean)
|
||||
field(:marked_as_deleted, non_null(:boolean))
|
||||
|
||||
field(:language, non_null(:language), resolve: dataloader(Accent.Language))
|
||||
|
||||
|
@ -52,7 +52,9 @@ defmodule Movement.Persisters.Base do
|
||||
context
|
||||
|> persist_operations()
|
||||
|> migrate_up_operations()
|
||||
|> tap(fn _ -> Oban.insert(ProjectStateChangeWorker.new(project_state_change_context)) end)
|
||||
|> tap(fn _ ->
|
||||
project_state_change_context.previous_project_state && Oban.insert(ProjectStateChangeWorker.new(project_state_change_context))
|
||||
end)
|
||||
end
|
||||
|
||||
@spec rollback(Movement.Context.t()) :: {Movement.Context.t(), [Operation.t()]}
|
||||
|
@ -0,0 +1,36 @@
|
||||
defmodule Accent.Repo.Migrations.ModifyRevisionForeignKeyToAllowDelete do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
execute("ALTER TABLE operations DROP CONSTRAINT operations_revision_id_fkey")
|
||||
|
||||
alter table(:operations) do
|
||||
modify(:revision_id, references(:revisions, type: :uuid, on_delete: :delete_all), null: true)
|
||||
end
|
||||
|
||||
execute("ALTER TABLE translations DROP CONSTRAINT translations_revision_id_fkey")
|
||||
execute("ALTER TABLE translations DROP CONSTRAINT translations_source_translation_id_fkey")
|
||||
|
||||
alter table(:translations) do
|
||||
modify(:revision_id, references(:revisions, type: :uuid, on_delete: :delete_all), null: false)
|
||||
|
||||
modify(
|
||||
:source_translation_id,
|
||||
references(:translations, type: :uuid, on_delete: :delete_all),
|
||||
null: true
|
||||
)
|
||||
end
|
||||
|
||||
execute("ALTER TABLE comments DROP CONSTRAINT comments_translation_id_fkey")
|
||||
|
||||
alter table(:comments) do
|
||||
modify(:translation_id, references(:translations, type: :uuid, on_delete: :delete_all), null: false)
|
||||
end
|
||||
|
||||
execute("ALTER TABLE translation_comments_subscriptions DROP CONSTRAINT translation_comments_subscriptions_translation_id_fkey")
|
||||
|
||||
alter table(:translation_comments_subscriptions) do
|
||||
modify(:translation_id, references(:translations, type: :uuid, on_delete: :delete_all), null: false)
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,15 @@
|
||||
defmodule Accent.Repo.Migrations.AddMarkedAsDeletedOnRevisions do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
alter table(:revisions) do
|
||||
add(:marked_as_deleted, :boolean)
|
||||
end
|
||||
|
||||
execute("UPDATE revisions SET marked_as_deleted = FALSE")
|
||||
|
||||
alter table(:revisions) do
|
||||
modify(:marked_as_deleted, :boolean, null: false, default: false)
|
||||
end
|
||||
end
|
||||
end
|
@ -5,6 +5,7 @@ defmodule AccentTest.Migrator.Down do
|
||||
Operation,
|
||||
PreviousTranslation,
|
||||
Repo,
|
||||
Revision,
|
||||
Translation
|
||||
}
|
||||
|
||||
@ -28,6 +29,7 @@ defmodule AccentTest.Migrator.Down do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_in_conflict",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
corrected_text: nil,
|
||||
proposed_text: "new proposed text",
|
||||
conflicted_text: "corrected_text",
|
||||
@ -65,6 +67,7 @@ defmodule AccentTest.Migrator.Down do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_in_proposed",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
corrected_text: nil,
|
||||
proposed_text: "new proposed text",
|
||||
conflicted_text: "proposed_text",
|
||||
@ -92,6 +95,7 @@ defmodule AccentTest.Migrator.Down do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_added_down",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
corrected_text: nil,
|
||||
proposed_text: "new text",
|
||||
conflicted_text: nil,
|
||||
@ -115,6 +119,7 @@ defmodule AccentTest.Migrator.Down do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_added_down",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
corrected_text: nil,
|
||||
proposed_text: "new text",
|
||||
conflicted_text: nil,
|
||||
@ -138,6 +143,7 @@ defmodule AccentTest.Migrator.Down do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
value_type: "",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
key: "to_be_added_down",
|
||||
corrected_text: nil,
|
||||
proposed_text: "new text",
|
||||
|
@ -106,12 +106,15 @@ defmodule AccentTest.Movement.Persisters.Base do
|
||||
end
|
||||
|
||||
test "new operation with removed translation" do
|
||||
revision = %Revision{} |> Repo.insert!()
|
||||
|
||||
translation =
|
||||
%Translation{
|
||||
key: "a",
|
||||
proposed_text: "A",
|
||||
conflicted: true,
|
||||
removed: true
|
||||
removed: true,
|
||||
revision_id: revision.id
|
||||
}
|
||||
|> Repo.insert!()
|
||||
|
||||
@ -120,6 +123,7 @@ defmodule AccentTest.Movement.Persisters.Base do
|
||||
action: "new",
|
||||
key: "a",
|
||||
text: "B",
|
||||
revision_id: revision.id,
|
||||
previous_translation: %PreviousTranslation{
|
||||
removed: true
|
||||
}
|
||||
@ -138,9 +142,12 @@ defmodule AccentTest.Movement.Persisters.Base do
|
||||
end
|
||||
|
||||
test "version operation with source translation" do
|
||||
revision = %Revision{} |> Repo.insert!()
|
||||
|
||||
translation =
|
||||
%Translation{
|
||||
key: "a",
|
||||
revision_id: revision.id,
|
||||
proposed_text: "A",
|
||||
conflicted: true,
|
||||
removed: true
|
||||
@ -152,6 +159,7 @@ defmodule AccentTest.Movement.Persisters.Base do
|
||||
action: "version_new",
|
||||
key: "a",
|
||||
text: "B",
|
||||
revision_id: revision.id,
|
||||
translation_id: translation.id
|
||||
}
|
||||
]
|
||||
@ -168,9 +176,12 @@ defmodule AccentTest.Movement.Persisters.Base do
|
||||
end
|
||||
|
||||
test "version operation add operation on source translation" do
|
||||
revision = %Revision{} |> Repo.insert!()
|
||||
|
||||
translation =
|
||||
%Translation{
|
||||
key: "a",
|
||||
revision_id: revision.id,
|
||||
proposed_text: "A",
|
||||
conflicted: true,
|
||||
removed: true
|
||||
@ -182,6 +193,7 @@ defmodule AccentTest.Movement.Persisters.Base do
|
||||
action: "version_new",
|
||||
key: "a",
|
||||
text: "B",
|
||||
revision_id: revision.id,
|
||||
translation_id: translation.id
|
||||
}
|
||||
]
|
||||
@ -211,6 +223,7 @@ defmodule AccentTest.Movement.Persisters.Base do
|
||||
translation =
|
||||
%Translation{
|
||||
key: "a",
|
||||
revision_id: revision.id,
|
||||
proposed_text: "A",
|
||||
conflicted: true,
|
||||
removed: true,
|
||||
@ -223,6 +236,7 @@ defmodule AccentTest.Movement.Persisters.Base do
|
||||
action: "update",
|
||||
key: "a",
|
||||
text: "B",
|
||||
revision_id: revision.id,
|
||||
value_type: "string",
|
||||
translation_id: translation.id,
|
||||
version_id: version.id
|
||||
|
@ -22,14 +22,25 @@ defmodule AccentTest.Movement.Persisters.NewVersion do
|
||||
setup do
|
||||
user = Repo.insert!(@user)
|
||||
language = Repo.insert!(%Language{name: "English", slug: Ecto.UUID.generate()})
|
||||
{:ok, project} = ProjectCreator.create(params: %{main_color: "#f00", name: "My project", language_id: language.id}, user: user)
|
||||
|
||||
{:ok, project} =
|
||||
ProjectCreator.create(
|
||||
params: %{main_color: "#f00", name: "My project", language_id: language.id},
|
||||
user: user
|
||||
)
|
||||
|
||||
revision = project |> Repo.preload(:revisions) |> Map.get(:revisions) |> hd()
|
||||
document = Repo.insert!(%Document{project_id: project.id, path: "test", format: "json"})
|
||||
|
||||
{:ok, [revision: revision, document: document, project: project, user: user]}
|
||||
end
|
||||
|
||||
test "builder fetch translations and process operations", %{revision: revision, user: user, project: project, document: document} do
|
||||
test "builder fetch translations and process operations", %{
|
||||
revision: revision,
|
||||
user: user,
|
||||
project: project,
|
||||
document: document
|
||||
} do
|
||||
translation =
|
||||
%Translation{
|
||||
key: "a",
|
||||
@ -51,6 +62,7 @@ defmodule AccentTest.Movement.Persisters.NewVersion do
|
||||
text: "B",
|
||||
translation_id: translation.id,
|
||||
value_type: "string",
|
||||
revision_id: revision.id,
|
||||
placeholders: []
|
||||
}
|
||||
]
|
||||
|
@ -23,6 +23,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_corrected",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
file_comment: "",
|
||||
corrected_text: nil,
|
||||
proposed_text: "proposed_text",
|
||||
@ -58,6 +59,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_merged",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
file_comment: "",
|
||||
corrected_text: "corrected_text",
|
||||
proposed_text: "proposed_text",
|
||||
@ -92,6 +94,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_merged",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
corrected_text: "corrected_text",
|
||||
proposed_text: "proposed_text",
|
||||
conflicted_text: nil,
|
||||
@ -119,6 +122,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_uncorrected",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
file_comment: "",
|
||||
file_index: 1,
|
||||
corrected_text: "new proposed text",
|
||||
@ -146,6 +150,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_uncorrected",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
file_comment: "",
|
||||
file_index: 1,
|
||||
corrected_text: "proposed_text",
|
||||
@ -173,6 +178,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_in_conflict",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
file_comment: "",
|
||||
file_index: 1,
|
||||
corrected_text: "corrected_text",
|
||||
@ -201,6 +207,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_in_conflict",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
file_comment: "",
|
||||
file_index: 1,
|
||||
corrected_text: "corrected_text",
|
||||
@ -228,6 +235,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_removed",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
corrected_text: "corrected_text",
|
||||
proposed_text: "proposed_text",
|
||||
conflicted: false,
|
||||
@ -249,6 +257,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_renewed",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
corrected_text: "corrected_text",
|
||||
proposed_text: "proposed_text",
|
||||
conflicted: false,
|
||||
@ -273,6 +282,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "to_be_rollbacked",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
corrected_text: "corrected_text",
|
||||
proposed_text: "proposed_text",
|
||||
conflicted: false,
|
||||
@ -298,6 +308,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
Repo.insert!(%Translation{
|
||||
value_type: "",
|
||||
key: "to_be_conflict_on_proposed",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
file_comment: "",
|
||||
file_index: 1,
|
||||
corrected_text: "corrected_text",
|
||||
@ -331,6 +342,7 @@ defmodule AccentTest.Movement.Migrator.Up do
|
||||
translation =
|
||||
Repo.insert!(%Translation{
|
||||
key: "updated_proposed",
|
||||
revision: Repo.insert!(%Revision{}),
|
||||
corrected_text: "corrected_text",
|
||||
proposed_text: "proposed_text",
|
||||
conflicted_text: "conflict",
|
||||
|
@ -8,8 +8,18 @@ defmodule AccentTest.RevisionDeleter do
|
||||
french_language = %Language{name: "french"} |> Repo.insert!()
|
||||
english_language = %Language{name: "english"} |> Repo.insert!()
|
||||
|
||||
master_revision = %Revision{language_id: french_language.id, project_id: project.id, master: true} |> Repo.insert!()
|
||||
slave_revision = %Revision{language_id: english_language.id, project_id: project.id, master: false, master_revision_id: master_revision.id} |> Repo.insert!()
|
||||
master_revision =
|
||||
%Revision{language_id: french_language.id, project_id: project.id, master: true}
|
||||
|> Repo.insert!()
|
||||
|
||||
slave_revision =
|
||||
%Revision{
|
||||
language_id: english_language.id,
|
||||
project_id: project.id,
|
||||
master: false,
|
||||
master_revision_id: master_revision.id
|
||||
}
|
||||
|> Repo.insert!()
|
||||
|
||||
{:ok, [master_revision: master_revision, slave_revision: slave_revision]}
|
||||
end
|
||||
@ -17,7 +27,7 @@ defmodule AccentTest.RevisionDeleter do
|
||||
test "delete slave", %{slave_revision: revision} do
|
||||
{:ok, _revision} = RevisionManager.delete(revision)
|
||||
|
||||
assert Repo.get(Revision, revision.id) == nil
|
||||
assert Repo.get(Revision, revision.id).marked_as_deleted
|
||||
end
|
||||
|
||||
test "delete master", %{master_revision: revision} do
|
||||
@ -29,7 +39,7 @@ defmodule AccentTest.RevisionDeleter do
|
||||
test "delete operations", %{slave_revision: revision} do
|
||||
operation = %Operation{action: "new", key: "a", revision_id: revision.id} |> Repo.insert!()
|
||||
|
||||
{:ok, _revision} = RevisionManager.delete(revision)
|
||||
Accent.Revisions.DeleteWorker.perform(%Oban.Job{args: %{"revision_id" => revision.id}})
|
||||
|
||||
assert Repo.get(Operation, operation.id) == nil
|
||||
end
|
||||
@ -37,7 +47,7 @@ defmodule AccentTest.RevisionDeleter do
|
||||
test "delete translations", %{slave_revision: revision} do
|
||||
translation = %Translation{key: "a", revision_id: revision.id} |> Repo.insert!()
|
||||
|
||||
{:ok, _revision} = RevisionManager.delete(revision)
|
||||
Accent.Revisions.DeleteWorker.perform(%Oban.Job{args: %{"revision_id" => revision.id}})
|
||||
|
||||
assert Repo.get(Translation, translation.id) == nil
|
||||
end
|
||||
|
@ -741,6 +741,7 @@
|
||||
"project_manage_languages_overview": {
|
||||
"list_languages": "Languages:",
|
||||
"revision_inserted_at_label": "Created",
|
||||
"revision_deleted_label": "The language is currently being removed from your project. It will automatically disappear once all operations are propagated in the system.",
|
||||
"master_badge": "master",
|
||||
"delete_revision_confirm": "Are you sure you want to remove this language from your project? This action cannot be rollbacked.",
|
||||
"delete_revision_button": "Remove this language",
|
||||
|
@ -741,6 +741,7 @@
|
||||
"project_manage_languages_overview": {
|
||||
"list_languages": "Langues :",
|
||||
"revision_inserted_at_label": "Créé",
|
||||
"revision_deleted_label": "La langue est en cours de suppression de votre projet. Elle disparaîtra automatiquement une fois toutes les opérations propagées dans le système.",
|
||||
"master_badge": "principale",
|
||||
"delete_revision_confirm": "Voulez-vous vraiment supprimer cette langue de votre projet ? Cette action ne peut pas être annulée.",
|
||||
"delete_revision_button": "Supprimer cette langue",
|
||||
|
@ -24,7 +24,7 @@ export default class OverviewItem extends Component<Args> {
|
||||
isDeleting = false;
|
||||
|
||||
@tracked
|
||||
isDeleted = false;
|
||||
isDeleted = this.args.revision.markedAsDeleted;
|
||||
|
||||
get name() {
|
||||
return this.args.revision.name || this.args.revision.language.name;
|
||||
|
@ -5,7 +5,14 @@
|
||||
font-size: 14px;
|
||||
|
||||
&.list-item--deleted {
|
||||
display: none;
|
||||
background: var(--background-light);
|
||||
border: 1px dashed var(--background-light-highlight);
|
||||
padding: 6px 10px;
|
||||
pointer-events: none;
|
||||
|
||||
.list-item-infos-date {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
&.list-item--deleting {
|
||||
|
@ -1,20 +1,26 @@
|
||||
<div
|
||||
local-class='list-item {{if @master "list-item--master"}} {{if this.isPromoting "list-item--promoting"}} {{if this.isDeleting "list-item--deleting"}} {{if
|
||||
this.deleted
|
||||
this.isDeleted
|
||||
"list-item--deleted"
|
||||
}}'
|
||||
>
|
||||
<div local-class='list-item-header'>
|
||||
<LinkTo @route='logged-in.project.manage-languages.edit' @models={{array @project.id @revision.id}} local-class='list-item-header-edit'>
|
||||
{{inline-svg 'assets/pencil.svg' local-class='item-edit-icon'}}
|
||||
</LinkTo>
|
||||
{{#unless this.isDeleted}}
|
||||
<LinkTo @route='logged-in.project.manage-languages.edit' @models={{array @project.id @revision.id}} local-class='list-item-header-edit'>
|
||||
{{inline-svg 'assets/pencil.svg' local-class='item-edit-icon'}}
|
||||
</LinkTo>
|
||||
{{/unless}}
|
||||
|
||||
<LinkTo @route='logged-in.project.revision.translations' @models={{array @project.id @revision.id}} local-class='list-link'>
|
||||
{{this.name}}
|
||||
<small local-class='list-link-small'>
|
||||
{{this.slug}}
|
||||
</small>
|
||||
</LinkTo>
|
||||
{{#if this.isDeleted}}
|
||||
<span local-class='list-link'>{{this.name}}</span>
|
||||
{{else}}
|
||||
<LinkTo @route='logged-in.project.revision.translations' @models={{array @project.id @revision.id}} local-class='list-link'>
|
||||
{{this.name}}
|
||||
<small local-class='list-link-small'>
|
||||
{{this.slug}}
|
||||
</small>
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
|
||||
{{#if @revision.isMaster}}
|
||||
<AccBadge local-class='masterBadge'>
|
||||
@ -26,25 +32,31 @@
|
||||
<div local-class='list-item-infos'>
|
||||
{{#unless @revision.isMaster}}
|
||||
<div local-class='list-item-infos-date'>
|
||||
{{t 'components.project_manage_languages_overview.revision_inserted_at_label'}}
|
||||
<TimeAgoInWordsTag @date={{@revision.insertedAt}} />
|
||||
</div>
|
||||
|
||||
<div local-class='list-item-actions'>
|
||||
{{#if (get @permissions 'promote_slave')}}
|
||||
<AsyncButton @loading={{this.isPromoting}} local-class='promoteSlaveButton' class='button--grey button--small' @onClick={{fn this.promoteRevision}}>
|
||||
{{inline-svg '/assets/chevron-top.svg' class='button-icon'}}
|
||||
{{t 'components.project_manage_languages_overview.promote_revision_master_button'}}
|
||||
</AsyncButton>
|
||||
{{/if}}
|
||||
|
||||
{{#if (get @permissions 'delete_slave')}}
|
||||
<AsyncButton @loading={{this.isDeleting}} class='button--red button--filled button--small' local-class='deleteSlaveButton' @onClick={{fn this.deleteRevision}}>
|
||||
{{inline-svg '/assets/x.svg' class='button-icon'}}
|
||||
{{t 'components.project_manage_languages_overview.delete_revision_button'}}
|
||||
</AsyncButton>
|
||||
{{#if this.isDeleted}}
|
||||
{{t 'components.project_manage_languages_overview.revision_deleted_label'}}
|
||||
{{else}}
|
||||
{{t 'components.project_manage_languages_overview.revision_inserted_at_label'}}
|
||||
<TimeAgoInWordsTag @date={{@revision.insertedAt}} />
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#unless this.isDeleted}}
|
||||
<div local-class='list-item-actions'>
|
||||
{{#if (get @permissions 'promote_slave')}}
|
||||
<AsyncButton @loading={{this.isPromoting}} local-class='promoteSlaveButton' class='button--grey button--small' @onClick={{fn this.promoteRevision}}>
|
||||
{{inline-svg '/assets/chevron-top.svg' class='button-icon'}}
|
||||
{{t 'components.project_manage_languages_overview.promote_revision_master_button'}}
|
||||
</AsyncButton>
|
||||
{{/if}}
|
||||
|
||||
{{#if (get @permissions 'delete_slave')}}
|
||||
<AsyncButton @loading={{this.isDeleting}} class='button--red button--filled button--small' local-class='deleteSlaveButton' @onClick={{fn this.deleteRevision}}>
|
||||
{{inline-svg '/assets/x.svg' class='button-icon'}}
|
||||
{{t 'components.project_manage_languages_overview.delete_revision_button'}}
|
||||
</AsyncButton>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
@ -18,6 +18,7 @@ export default gql`
|
||||
name
|
||||
slug
|
||||
isMaster
|
||||
markedAsDeleted
|
||||
insertedAt
|
||||
|
||||
language {
|
||||
|
Loading…
Reference in New Issue
Block a user