Skip to content

Commit

Permalink
[ENHC0010033] List samples within clone dialog (#640)
Browse files Browse the repository at this point in the history
* adding infinite scrolling

* playing with the idea of adding a loading skeleton like with lazy loading

* adding the selected samples scrollable list to the clone samples dialog

* adding tests

* starting refactoring

* more refactoring

* displaying total selected count

* adding missing french translations

* trying to fix a test

* trying to fix a test

* trying to fix a test

* trying to fix a test

* trying to fix a test

* trying to fix a test

* reordering assertions

* renaming default_skeleton
  • Loading branch information
ksierks authored Jun 18, 2024
1 parent 4ed99dd commit b7debb8
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 90 deletions.
11 changes: 10 additions & 1 deletion app/javascript/controllers/infinite_scroll_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createHiddenInput } from '../utilities/form';

export default class extends Controller {
static outlets = ["selection"];
static targets = ["all", "pageForm", "pageFormContent", "scrollable"];
static targets = ["all", "pageForm", "pageFormContent", "scrollable", "summary"];
static values = {
fieldName: String,
pagedFieldName: String
Expand All @@ -15,6 +15,7 @@ export default class extends Controller {
this.allIds = this.selectionOutlet.getStoredSamples();
this.#makePagedHiddenInputs();
this.#makeAllHiddenInputs();
this.#replaceCountPlaceholder();
}

scroll() {
Expand All @@ -26,6 +27,14 @@ export default class extends Controller {
}
}

#replaceCountPlaceholder(){
const summary = this.summaryTarget;
summary.textContent = summary.textContent.replace(
"COUNT_PLACEHOLDER",
this.selectionOutlet.getNumSelected(),
);
}

#makePagedHiddenInputs() {
const itemsPerPage = 100;
const start = (this.#page - 1) * itemsPerPage;
Expand Down
84 changes: 66 additions & 18 deletions app/views/projects/samples/clones/_dialog.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,76 @@
<%= dialog.with_header(title: t(".title")) %>
<%= dialog.with_section do %>
<%= turbo_frame_tag "clone_samples_dialog_content" do %>
<%= form_for(:clone, url: namespace_project_samples_clone_path, method: :post) do |form| %>
<div
data-controller="sessionstorage-amend-form"
data-sessionstorage-amend-form-storage-key-value=<%=namespace_project_samples_url%>
data-sessionstorage-amend-form-target="field"
data-sessionstorage-amend-form-field-name-value="clone[sample_ids][]"
/>
<div
data-controller="infinite-scroll"
data-infinite-scroll-selection-outlet='#samples-table'
data-infinite-scroll-field-name-value="clone[sample_ids][]"
data-infinite-scroll-paged-field-name-value="sample_ids[]"
>
<%= form_with(
url: list_namespace_project_samples_path,
data: { "infinite-scroll-target": "pageForm" }
) do %>
<div data-infinite-scroll-target="pageFormContent"></div>
<% end %>

<div class="grid gap-4">
<div class="form-field">
<%= form.label :new_project_id, t(".new_project_id") %>
<%= form.collection_select(:new_project_id, @projects, :id, :full_path) %>
</div>
<p
data-infinite-scroll-target="summary"
class="
text-base leading-relaxed text-slate-500 dark:text-slate-400
"
>
<%= t(".description") %>
</p>
<div>
<%= form.submit t(".submit_button"),
class: "button button--size-default button--state-primary",
disabled: @projects.count.zero?,
data: {
action: "click->sessionstorage-amend-form#clear"
} %>
<div class="block mb-1 text-sm font-medium text-slate-900 dark:text-white">
<%= t(".samples") %>
</div>
<div
class="
overflow-y-auto max-h-[300px] border border-slate-300 rounded-md block w-full
p-2.5 dark:bg-slate-800 dark:border-slate-600
"
data-action="scroll->infinite-scroll#scroll"
data-infinite-scroll-target="scrollable"
>
<%= turbo_frame_tag "list_select_samples" do %>
<%= render partial: "shared/loading/samples_list_skeleton" %>
<% end %>
</div>
</div>

<%= form_for(:clone, url: namespace_project_samples_clone_path, method: :post,
data: {
controller: "spinner",
action:"turbo:submit-start->spinner#submitStart turbo:submit-end->spinner#submitEnd"
}
) do |form| %>
<div class="grid gap-4">
<div class="form-field">
<%= form.label :new_project_id, t(".new_project_id") %>
<%= form.collection_select(:new_project_id, @projects, :id, :full_path) %>
</div>
<div class="hidden" data-infinite-scroll-target="all"></div>
<div>
<%= form.submit t(".submit_button"),
class: "button button--size-default button--state-primary",
disabled: @projects.count.zero?,
data: {
action: "click->infinite-scroll#clear",
"spinner-target": "submit",
} %>
</div>
</div>
<% end %>
</div>
<% end %>
</div>

<%= render partial: "shared/loading/spinner",
locals: {
spinner_message: t(".spinner_message"),
} %>
<% end %>
<% end %>
<% end %>
119 changes: 59 additions & 60 deletions app/views/projects/samples/transfers/_dialog.html.erb
Original file line number Diff line number Diff line change
@@ -1,78 +1,77 @@
<%= viral_dialog(open: open) do |dialog| %>
<%= dialog.with_header(title: t(".title")) %>
<%= dialog.with_section do %>
<div
data-controller="infinite-scroll"
data-infinite-scroll-selection-outlet='#samples-table'
data-infinite-scroll-field-name-value="transfer[sample_ids][]"
data-infinite-scroll-paged-field-name-value="sample_ids[]"
>
<%= form_with(
<%= turbo_frame_tag "transfer_samples_dialog_content" do %>
<div
data-controller="infinite-scroll"
data-infinite-scroll-selection-outlet='#samples-table'
data-infinite-scroll-field-name-value="transfer[sample_ids][]"
data-infinite-scroll-paged-field-name-value="sample_ids[]"
>
<%= form_with(
url: list_namespace_project_samples_path,
data: { "infinite-scroll-target": "pageForm" }
) do %>
<div data-infinite-scroll-target="pageFormContent"></div>
<% end %>
<div
class="overflow-y-auto max-h-[300px] mb-4"
data-action="scroll->infinite-scroll#scroll"
data-infinite-scroll-target="scrollable"
>
<%= turbo_frame_tag "list_select_samples" do %>
<div role="status" class="max-w-sm animate-pulse">
<% 4.times do %>
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[360px] mb-2.5"></div>
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 mb-2.5"></div>
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[330px] mb-2.5"></div>
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[300px] mb-2.5"></div>
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[360px] mb-2.5"></div>
<% end %>
<span class="sr-only"><%= t(:".loading") %></span>
</div>
<div data-infinite-scroll-target="pageFormContent"></div>
<% end %>
</div>

<%= turbo_frame_tag "transfer_samples_dialog_content" do %>
<%= form_for(:transfer, url: namespace_project_samples_transfer_path, method: :post,
<div class="grid gap-4">
<p
data-infinite-scroll-target="summary"
class="
text-base leading-relaxed text-slate-500 dark:text-slate-400
"
>
<%= t(".description") %>
</p>
<div>
<div class="block mb-1 text-sm font-medium text-slate-900 dark:text-white">
<%= t(".samples") %>
</div>
<div
class="
overflow-y-auto max-h-[300px] border border-slate-300 rounded-md block w-full
p-2.5 dark:bg-slate-800 dark:border-slate-600
"
data-action="scroll->infinite-scroll#scroll"
data-infinite-scroll-target="scrollable"
>
<%= turbo_frame_tag "list_select_samples" do %>
<%= render partial: "shared/loading/samples_list_skeleton" %>
<% end %>
</div>
</div>

<%= form_for(:transfer, url: namespace_project_samples_transfer_path, method: :post,
data: {
controller: "spinner",
action:"turbo:submit-start->spinner#submitStart turbo:submit-end->spinner#submitEnd"
}
) do |form| %>
<div class="grid gap-4">
<div class="form-field">
<%= form.label :new_project_id, t(".new_project_id") %>
<%= form.collection_select(:new_project_id, @projects, :id, :full_path) %>
</div>
<div class="hidden" data-infinite-scroll-target="all"></div>
<div>
<%= form.submit t(".submit_button"),
class: "button button--size-default button--state-primary",
disabled: @projects.count.zero?,
data: {
action: "click->infinite-scroll#clear",
"spinner-target": "submit",
"turbo-submits-with": t(:".loading"),
} %>
<div class="grid gap-4">
<div class="form-field">
<%= form.label :new_project_id, t(".new_project_id") %>
<%= form.collection_select(:new_project_id, @projects, :id, :full_path) %>
</div>
<div class="hidden" data-infinite-scroll-target="all"></div>
<div>
<%= form.submit t(".submit_button"),
class: "button button--size-default button--state-primary",
disabled: @projects.count.zero?,
data: {
action: "click->infinite-scroll#clear",
"spinner-target": "submit",
} %>
</div>
</div>
</div>
<% end %>
<% end %>
</div>

<div
role="status"
id="spinner"
class="
hidden backdrop-blur-sm absolute h-full w-full -translate-x-1/2 -translate-y-1/2
top-2/4 left-1/2 grid place-items-center
"
>
<div class="grid place-items-center">
<%= viral_icon(name: :loading, classes: "animate-spin text-primary-500") %>
<span class="text-black dark:text-white"><%= t(:".spinner") %>.</span>
<% end %>
</div>
</div>
</div>

<%= render partial: "shared/loading/spinner",
locals: {
spinner_message: t(".spinner_message"),
} %>
<% end %>
<% end %>
<% end %>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
<% end %>
<%= turbo_stream.update "samples_dialog", partial: "dialog", locals: { open: false } %>
<% else %>
<%= turbo_stream.remove "list_select_samples" %>
<%= turbo_stream.replace "transfer_samples_dialog_content",
partial: "projects/samples/shared/errors",
locals: {
Expand Down
9 changes: 9 additions & 0 deletions app/views/shared/loading/_samples_list_skeleton.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div role="status" class="max-w-sm animate-pulse">
<% 4.times do %>
<div class="py-1">
<div class="h-4 bg-gray-200 rounded w-1/2 mb-2"></div>
<div class="h-3 bg-gray-200 rounded w-2/3"></div>
</div>
<% end %>
<span class="sr-only"><%= t(:".loading") %></span>
</div>
13 changes: 13 additions & 0 deletions app/views/shared/loading/_spinner.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div
role="status"
id="spinner"
class="
hidden backdrop-blur-sm absolute h-full w-full -translate-x-1/2 -translate-y-1/2
top-2/4 left-1/2 grid place-items-center
"
>
<div class="grid place-items-center">
<%= viral_icon(name: :loading, classes: "animate-spin text-primary-500") %>
<span class="text-black dark:text-white"><%= spinner_message %>.</span>
</div>
</div>
13 changes: 11 additions & 2 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1184,10 +1184,11 @@ en:
transfers:
dialog:
title: Transfer Samples
description: The following COUNT_PLACEHOLDER samples are about to be transferred, which will result in these samples no longer being accessible in this project. Maintainers can only transfer samples to another project within the same hierarchy.
samples: Samples
new_project_id: Project to transfer samples to
submit_button: Submit
loading: Loading...
spinner: Transferring samples, this might take a while...
spinner_message: Transferring samples, this might take a while...
create:
success: Samples were successfully transferred.
error: "The following list of samples failed to transfer:"
Expand All @@ -1199,8 +1200,11 @@ en:
no_samples_cloned_error: "Samples were not cloned for the following reasons:"
dialog:
title: Clone Samples
description: The following COUNT_PLACEHOLDER samples are about to be cloned to another project.
samples: Samples
new_project_id: Project to clone samples to
submit_button: Submit
spinner_message: Cloning samples, this might take a while...
metadata:
deletions:
destroy:
Expand Down Expand Up @@ -1675,3 +1679,8 @@ en:
alert:
list:
danger: Danger
loading:
samples_list_skeleton:
loading: Loading...
spinner:
loading: Loading...
12 changes: 11 additions & 1 deletion config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1178,10 +1178,12 @@ fr:
transfers:
dialog:
title: Transfer Samples
description: The following COUNT_PLACEHOLDER samples are about to be transferred, which will result in these samples no longer being accessible in this project. Maintainers can only transfer samples to another project within the same hierarchy.
samples: Samples
new_project_id: Project to transfer samples to
submit_button: Submit
loading: Loading...
spinner: Transferring samples, this might take a while...
spinner_message: Transferring samples, this might take a while...
create:
success: Samples were successfully transferred.
error: "The following list of samples failed to transfer:"
Expand All @@ -1193,8 +1195,11 @@ fr:
no_samples_cloned_error: "Samples were not cloned for the following reasons:"
dialog:
title: Clone Samples
description: The following COUNT_PLACEHOLDER samples are about to be cloned to another project.
samples: Samples
new_project_id: Project to clone samples to
submit_button: Submit
spinner_message: Cloning samples, this might take a while...
metadata:
deletions:
destroy:
Expand Down Expand Up @@ -1667,3 +1672,8 @@ fr:
alert:
list:
danger: Danger
loading:
samples_list_skeleton:
loading: Loading...
spinner:
loading: Loading...
Loading

0 comments on commit b7debb8

Please sign in to comment.