diff --git a/app/components/nextflow/samplesheet/column_component.html.erb b/app/components/nextflow/samplesheet/column_component.html.erb
index 278e022ee2..caf265114d 100644
--- a/app/components/nextflow/samplesheet/column_component.html.erb
+++ b/app/components/nextflow/samplesheet/column_component.html.erb
@@ -57,17 +57,5 @@
id="<%= "metadata-#{header}-column" %>"
class="dark:bg-slate-700 bg-slate-50"
>
- <% samples.each_with_index do |sample, index| %>
-
- <%= fields_for "workflow_execution[samples_workflow_executions_attributes][#{index}]" do |s| %>
- <%= s.fields_for "samplesheet_params" do |fields| %>
- <%= render_cell_type(header, property, sample, fields, index, workflow_params) %>
- <% end %>
- <% end %>
-
- <% end %>
diff --git a/app/components/nextflow/samplesheet/column_component.rb b/app/components/nextflow/samplesheet/column_component.rb
index 8e01c24508..e2a6afe4c3 100644
--- a/app/components/nextflow/samplesheet/column_component.rb
+++ b/app/components/nextflow/samplesheet/column_component.rb
@@ -56,7 +56,7 @@ def filter_files_by_pattern(files, pattern)
end
def render_sample_cell(sample_identifier)
- render(Samplesheet::SampleCellComponent.new(sample_identifier:))
+ # render(Samplesheet::SampleCellComponent.new(sample_identifier:))
end
def render_metadata_cell(sample, name, fields, index)
diff --git a/app/components/nextflow/samplesheet/sample_cell_component.rb b/app/components/nextflow/samplesheet/sample_cell_component.rb
index 553a659978..d1f399add8 100644
--- a/app/components/nextflow/samplesheet/sample_cell_component.rb
+++ b/app/components/nextflow/samplesheet/sample_cell_component.rb
@@ -4,12 +4,6 @@ module Nextflow
module Samplesheet
# Render a single cell of a Nextflow samplesheet for a given sample
class SampleCellComponent < Component
- erb_template <<~ERB
-
- <%= @sample_identifier %>
-
- ERB
-
def initialize(sample_identifier:)
@sample_identifier = sample_identifier
end
diff --git a/app/components/nextflow/samplesheet_component.html.erb b/app/components/nextflow/samplesheet_component.html.erb
index 6739dad950..474014d8a3 100644
--- a/app/components/nextflow/samplesheet_component.html.erb
+++ b/app/components/nextflow/samplesheet_component.html.erb
@@ -2,6 +2,9 @@
<%= samples_workflow_executions_attributes %>
+
+ <%= @properties.to_json %>
+
-
+
+
+
+
+
+
+
+
+ CELL_PLACEHOLDER
+
+
+
+
+
+
+
+
+
+ <%= link_to new_workflow_executions_file_selector_path(
+ "file_selector[attachable_id]": "ATTACHABLE_ID_PLACEHOLDER",
+ "file_selector[attachable_type]": "ATTACHABLE_TYPE_PLACEHOLDER",
+ "file_selector[index]": "INDEX_PLACEHOLDER",
+ "file_selector[selected_id]": "SELECTED_ID_PLACEHOLDER",
+ "file_selector[property]": "PROPERTY_PLACEHOLDER",
+ "file_selector[required_properties]": @required_properties,
+ "file_selector[file_type]": "FILE_TYPE_PLACEHOLDER",
+ "file_selector[file_selector_arguments]": {workflow_params:, patterns:}
+),
+data: {
+ turbo_stream: "true",
+} do %>
+
"
+ class="
+ w-full focus:ring-primary-500 focus:border-primary-500 p-2 dark:bg-inherit
+ bg-inherit dark:placeholder-slate-400 text-inherit text-sm
+ dark:focus:ring-primary-500 dark:focus:border-primary-500 cursor-pointer
+ hover:border-slate-300 border-transparent border-2
+ "
+ <% if @required_properties.present? && @required_properties.include?(@property) %>
+ data-file-missing="<%= @selected.empty? ? "true" : "false" %>"
+ <% end %>
+ >
+ <%# <%= @selected.empty? ? t(".no_selected_file") : @selected[:filename] %>
+ CELL_VALUE_PLACEHOLDER
+
+ <% end %>
+
+
+
+
+
+
+ METADATA_VALUE_PLACEHOLDER
+
+
+
+
+
+
diff --git a/app/components/nextflow/samplesheet_component.rb b/app/components/nextflow/samplesheet_component.rb
index 42df2c2c50..6a7b8a4910 100644
--- a/app/components/nextflow/samplesheet_component.rb
+++ b/app/components/nextflow/samplesheet_component.rb
@@ -3,7 +3,8 @@
module Nextflow
# Render the contents of a Nextflow samplesheet to a table
class SamplesheetComponent < Component
- attr_reader :properties, :samples, :required_properties, :metadata_fields, :namespace_id, :workflow_params
+ attr_reader :properties, :samples, :required_properties, :metadata_fields, :namespace_id, :workflow_params,
+ :patterns
FILE_CELL_TYPES = %w[fastq_cell file_cell].freeze
@@ -13,6 +14,7 @@ def initialize(schema:, samples:, fields:, namespace_id:, workflow_params:)
@metadata_fields = fields
@required_properties = schema['items']['required'] || []
@workflow_params = workflow_params
+ @patterns = {}
extract_properties(schema)
end
@@ -28,7 +30,8 @@ def samples_workflow_executions_attributes
def samples_workflow_execution_attributes(sample)
{
'sample_id' => sample.id,
- 'samplesheet_params' => sample_samplesheet_params(sample)
+ 'samplesheet_params' => sample_samplesheet_params(sample),
+ 'patterns' => {}
}
end
@@ -36,26 +39,53 @@ def sample_samplesheet_params(sample) # rubocop:disable Metrics/CyclomaticComple
@properties.to_h do |name, property|
case property['cell_type']
when 'sample_cell'
- [name, sample.puid]
+ [name, { form_value: sample.puid, cell_type: 'sample_cell', cell_value: sample.puid }]
when 'sample_name_cell'
- [name, sample.name]
+ [name, { form_value: sample.name, cell_type: 'sample_name_cell', cell_value: sample.name }]
when 'fastq_cell'
- [name, sample.attachments.empty? ? '' : sample.most_recent_fastq_file(name, @workflow_params)[:global_id]]
+ [name,
+ file_samplesheet_values(sample.attachments.empty? ? nil : sample.most_recent_fastq_file(name,
+ @workflow_params))]
when 'file_cell'
- [name, sample.most_recent_other_file(property['autopopulate'], property['pattern'])[:global_id]]
+ [name,
+ file_samplesheet_values(sample.most_recent_other_file(property['autopopulate'], property['pattern']))]
when 'metadata_cell'
- [name, sample.metadata.fetch(name, '')]
+ [name, metadata_samplesheet_values(sample, name)]
when 'dropdown_cell' || 'input_cell'
- [name, '']
+ [name, { form_value: '', cell_type: property['cell_type'], cell_value: '' }]
end
end
end
+ def file_samplesheet_values(file)
+ { form_value: file.empty? ? '' : file[:global_id],
+ cell_type: 'file_cell',
+ cell_value: file.empty? ? I18n.t('nextflow.samplesheet.file_cell_component.no_selected_file') : file[:filename],
+ attachment_id: file.empty? ? '' : file[:id] }
+ end
+
+ def metadata_samplesheet_values(sample, name)
+ metadata = sample.metadata.fetch(name, '')
+ if metadata.empty?
+ { form_value: '',
+ cell_type: 'text',
+ cell_value: nil }
+ else
+ { form_value: metadata,
+ cell_type: 'metadata_cell',
+ cell_value: metadata }
+ end
+ end
+
def extract_properties(schema)
@properties = schema['items']['properties']
@properties.each do |property, entry|
@properties[property]['required'] = schema['items']['required'].include?(property)
@properties[property]['cell_type'] = identify_cell_type(property, entry)
+ if @properties[property]['pattern'] && %w[fastq_cell
+ file_cell].include?(@properties[property]['cell_type'])
+ @patterns[property] = @properties[property]['pattern']
+ end
end
if @required_properties.include?('fastq_1') && @required_properties.include?('fastq_2')
diff --git a/app/components/nextflow_component.html.erb b/app/components/nextflow_component.html.erb
index 57188078d2..8334f8dba9 100644
--- a/app/components/nextflow_component.html.erb
+++ b/app/components/nextflow_component.html.erb
@@ -3,6 +3,7 @@
data-nextflow--samplesheet-attachments-error-value="<%= t(".attachments_error") %>"
data-nextflow--samplesheet-submission-error-value="<%= t(".submission_error") %>"
data-nextflow--samplesheet-url-value="<%= url %>"
+ data-nextflow--samplesheet-workflow-value="<%= {name: @workflow.name, version: @workflow.version }.to_json%>"
data-action="
nextflow--autofilled-cell:sendAutofilledInputData->nextflow--samplesheet#updateAutofilledSamplesheetData
"
diff --git a/app/controllers/workflow_executions/file_selector_controller.rb b/app/controllers/workflow_executions/file_selector_controller.rb
index 3867c48253..88fbc63c59 100644
--- a/app/controllers/workflow_executions/file_selector_controller.rb
+++ b/app/controllers/workflow_executions/file_selector_controller.rb
@@ -8,6 +8,8 @@ class FileSelectorController < ApplicationController
before_action :listing_attachments, only: %i[new create]
def new
+ puts 'hihihhihi'
+ puts file_selector_params
render turbo_stream: turbo_stream.update('file_selector_dialog',
partial: 'file_selector_dialog',
locals: { file_selector_params:, open: true }), status: :ok
@@ -33,7 +35,7 @@ def file_selector_params
:file_type,
required_properties: [],
file_selector_arguments: [
- :pattern, { workflow_params: %i[name version] }
+ { patterns: {} }, { workflow_params: %i[name version] }
]
)
end
@@ -45,10 +47,10 @@ def listing_attachments # rubocop:disable Metrics/AbcSize
file_selector_params['property'], file_selector_params['file_selector_arguments']['workflow_params']
)
when 'other'
- @listing_attachments = if file_selector_params['file_selector_arguments']['pattern']
+ @listing_attachments = if file_selector_params['file_selector_arguments']['patterns'][file_selector_params['property']]
@attachable.filter_files_by_pattern(
@attachable.sorted_files[:singles] || [],
- file_selector_params['file_selector_arguments']['pattern']
+ file_selector_params['file_selector_arguments']['patterns'][file_selector_params['property']]
)
else
sample.sorted_files[:singles] || []
@@ -77,7 +79,7 @@ def attachments
byte_size: attachment.byte_size,
created_at: attachment.created_at,
metadata: attachment.metadata }
- return unless file_selector_params['property'] == 'fastq_1' || file_selector_params['property'] == 'fastq_2'
+ return unless %w[fastq_1 fastq_2].include?(file_selector_params['property'])
assign_associated_attachment_params(attachment)
end
diff --git a/app/javascript/controllers/nextflow/autofilled_cell_controller.js b/app/javascript/controllers/nextflow/autofilled_cell_controller.js
index 3c8f9cebda..f2046232b7 100644
--- a/app/javascript/controllers/nextflow/autofilled_cell_controller.js
+++ b/app/javascript/controllers/nextflow/autofilled_cell_controller.js
@@ -5,6 +5,7 @@ export default class extends Controller {
static values = { inputName: { type: String }, inputValue: { type: String } };
connect() {
+ console.log("autofilled");
this.sendAutofilledInputData();
}
diff --git a/app/javascript/controllers/nextflow/samplesheet_controller.js b/app/javascript/controllers/nextflow/samplesheet_controller.js
index bbbfc0a2e6..3b0903b998 100644
--- a/app/javascript/controllers/nextflow/samplesheet_controller.js
+++ b/app/javascript/controllers/nextflow/samplesheet_controller.js
@@ -9,11 +9,19 @@ export default class extends Controller {
"errorMessage",
"form",
"workflowAttributes",
+ "samplesheetProperties",
+ "cellContainer",
+ "sampleIdentifierCell",
+ "dropdownCell",
+ "fileCell",
+ "metadataCell",
+ "textCell",
];
static values = {
attachmentsError: { type: String },
submissionError: { type: String },
url: { type: String },
+ workflow: { type: Object },
};
#error_state = ["border-red-300", "dark:border-red-800"];
@@ -22,32 +30,42 @@ export default class extends Controller {
// The samplesheet will use FormData, allowing us to create the inputs of a form without the associated DOM elements.
#formData = new FormData();
+ #currentPage = 1;
+ #samplesheetProperties = JSON.parse(
+ this.samplesheetPropertiesTarget.innerHTML,
+ );
+ #columnNames = Object.keys(this.#samplesheetProperties);
connect() {
+ console.log("properties");
+ console.log(this.#samplesheetProperties);
if (this.hasWorkflowAttributesTarget) {
+ this.samplesheetParams = JSON.parse(
+ this.workflowAttributesTarget.innerText,
+ );
this.#setInitialSamplesheetData();
+ this.#loadPageData();
}
}
#setInitialSamplesheetData() {
- const samples_workflow_attrs = JSON.parse(
- this.workflowAttributesTarget.innerText,
- );
- for (const index in samples_workflow_attrs) {
- for (const sample_attrs in samples_workflow_attrs[index]) {
+ console.log("params");
+ console.log(this.samplesheetParams);
+ for (const index in this.samplesheetParams) {
+ for (const sample_attrs in this.samplesheetParams[index]) {
if (sample_attrs == "sample_id") {
// specifically adds sample to form
this.#setFormData(
`workflow_execution[samples_workflow_executions_attributes][${index}][${sample_attrs}]`,
- samples_workflow_attrs[index][sample_attrs],
+ this.samplesheetParams[index][sample_attrs],
);
continue;
}
- for (const property in samples_workflow_attrs[index][sample_attrs]) {
+ for (const property in this.samplesheetParams[index][sample_attrs]) {
// adds all remaining sample data to form (files, metadata, etc.)
this.#setFormData(
`workflow_execution[samples_workflow_executions_attributes][${index}][${sample_attrs}][${property}]`,
- samples_workflow_attrs[index][sample_attrs][property],
+ this.samplesheetParams[index][sample_attrs][property]["form_value"],
);
}
}
@@ -149,4 +167,167 @@ export default class extends Controller {
this.errorTarget.classList.remove("hidden");
this.errorMessageTarget.innerHTML = message;
}
+
+ #loadPageData() {
+ let startingIndex = (this.#currentPage - 1) * 5;
+ this.#columnNames.forEach((columnName) => {
+ let columnNode = document.getElementById(`metadata-${columnName}-column`);
+ for (let i = 0; i < 1; i++) {
+ let container = this.#generateCellContainer(columnNode);
+ switch (this.#samplesheetProperties[columnName]["cell_type"]) {
+ case "sample_cell":
+ case "sample_name_cell":
+ this.#generateSampleCell(container, columnName, i);
+ break;
+ case "dropdown_cell":
+ this.#generateDropdownCell(
+ container,
+ columnName,
+ i,
+ this.#samplesheetProperties[columnName]["enum"],
+ );
+ break;
+ case "fastq_cell":
+ case "file_cell":
+ this.#generateFileCell(container, columnName, i);
+ break;
+ case "metadata_cell":
+ this.#generateMetadataCell(container, columnName, i);
+ break;
+ case "input_cell":
+ this.#generateTextCell(container, columnName, i);
+ break;
+ default:
+ this.#generateSampleCell(container, columnName, i);
+ }
+ }
+ });
+ // 1 -> 0-4
+ // 2 -> 5-9
+ // 3 -> 10-14
+ // 4 -> 15-19
+ }
+
+ // inserting the template html then requerying it out via lastElementChild turns the node from textNode into an
+ // HTML element we can manipulate via appendChild, insertHTML, etc.
+ #generateCellContainer(columnNode) {
+ let newCellContainer = this.cellContainerTarget.innerHTML;
+ columnNode.insertAdjacentHTML("beforeend", newCellContainer);
+ return columnNode.lastElementChild;
+ }
+
+ #generateSampleCell(container, columnName, index) {
+ let childNode = this.sampleIdentifierCellTarget.innerHTML.replace(
+ /CELL_PLACEHOLDER/g,
+ this.samplesheetParams[index]["samplesheet_params"][columnName][
+ "cell_value"
+ ],
+ );
+ container.insertAdjacentHTML("beforeend", childNode);
+ }
+
+ #generateDropdownCell(container, columnName, index, options) {
+ let childNode = this.dropdownCellTarget.innerHTML
+ .replace(/INDEX_PLACEHOLDER/g, index)
+ .replace(/COLUMN_NAME_PLACEHOLDER/g, columnName);
+
+ container.insertAdjacentHTML("beforeend", childNode);
+ let select = container.querySelector("select");
+ for (let j = 0; j < options.length; j++) {
+ let option = document.createElement("option");
+ option.value = options[j];
+ option.innerHTML = options[j];
+ select.appendChild(option);
+ }
+ // TODO SET SELECTED VALUE
+ }
+
+ #generateFileCell(container, columnName, index) {
+ let childNode = this.fileCellTarget.innerHTML
+ .replace(/INDEX_PLACEHOLDER/g, index)
+ .replace(/PROPERTY_PLACEHOLDER/g, columnName)
+ .replace(
+ /ATTACHABLE_ID_PLACEHOLDER/g,
+ this.samplesheetParams[index]["sample_id"],
+ )
+ .replace(/ATTACHABLE_TYPE_PLACEHOLDER/g, "Sample")
+ .replace(
+ /SELECTED_ID_PLACEHOLDER/g,
+ this.samplesheetParams[index]["samplesheet_params"][columnName][
+ "attachment_id"
+ ],
+ )
+ .replace(
+ /FILE_TYPE_PLACEHOLDER/g,
+ this.#samplesheetProperties[columnName]["cell_type"] == "fastq_cell"
+ ? "fastq"
+ : "other",
+ )
+ .replace(
+ /CELL_VALUE_PLACEHOLDER/g,
+ this.samplesheetParams[index]["samplesheet_params"][columnName][
+ "cell_value"
+ ],
+ );
+ container.insertAdjacentHTML("beforeend", childNode);
+
+ // sets the verification attribute for required file cells
+ if (this.#samplesheetProperties[columnName]["required"]) {
+ let fileNode = document.getElementById(
+ `${this.samplesheetParams[index]["sample_id"]}_${columnName}`,
+ );
+ fileNode.setAttribute(
+ "data-file-missing",
+ this.samplesheetParams[index]["samplesheet_params"][columnName][
+ "attachment_id"
+ ]
+ ? "false"
+ : "true",
+ );
+ }
+ }
+
+ #generateMetadataCell(container, columnName, index) {
+ if (
+ this.samplesheetParams[index]["samplesheet_params"][columnName][
+ "form_value"
+ ]
+ ) {
+ let childNode = his.metadataCellTarget.innerHTML.replace(
+ /METADATA_VALUE_PLACEHOLDER/g,
+ his.samplesheetParams[index]["samplesheet_params"][columnName][
+ "form_value"
+ ],
+ );
+ container.insertAdjacentHTML("beforeend", childNode);
+ } else {
+ this.#generateTextCell(container, columnName, index);
+ }
+ }
+
+ #generateTextCell(container, columnName, index) {
+ let childNode = this.textCellTarget.innerHTML
+ .replace(
+ /NAME_PLACEHOLDER/g,
+ `workflow_execution[samples_workflow_executions_attributes][${index}][samplesheet_params][${columnName}]`,
+ )
+ .replace(
+ /ID_PLACEHOLDER/g,
+ `workflow_execution_samples_workflow_executions_attributes_${index}_samplesheet_params_${columnName}`,
+ );
+
+ container.insertAdjacentHTML("beforeend", childNode);
+ const form_value =
+ this.samplesheetParams[index]["samplesheet_params"][columnName][
+ "form_value"
+ ];
+
+ if (form_value) {
+ container.lastElementChild.value = form_value;
+ }
+ }
}
+
+// console.log(this.#samplesheetProperties);
+
+// console.log(this.samplesheetParams);
diff --git a/config/pipelines/pipelines.json b/config/pipelines/pipelines.json
index 0911993c55..d09a2373c0 100644
--- a/config/pipelines/pipelines.json
+++ b/config/pipelines/pipelines.json
@@ -19,5 +19,18 @@
"executable": false
}
]
+ }, {
+ "url": "https://github.com/phac-nml/fastmatchirida",
+ "name": "phac-nml/fastmatchirida",
+ "description": "IRIDA Next Fast Match Pipeline",
+ "versions": [
+ {
+ "name": "0.1.0"
+ }
+ ]
}
+
+
+, { "url": "https://github.com/phac-nml/mikrokondo", "name": "phac-nml/mikrokondo", "description": "Mikrokondo", "versions": [ { "name": "0.5.0" } ] }
+
]