Skip to content

Commit

Permalink
Merge branch 'release-23.10.1' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
deepsidhu85 committed Dec 14, 2023
2 parents 5b4bec8 + 3486466 commit 6bc942e
Show file tree
Hide file tree
Showing 12 changed files with 338 additions and 196 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Changelog

# [23.10.1] - 2023/12/07
* [UI]: Fixed issue where filter inputs required focus when they are opened on the project samples page. See [PR 1503](https://github.com/phac-nml/irida/pull/1503)
* [UI]: Fixed bug preventing sorting and paging on the project members page. See [PR 1504](https://github.com/phac-nml/irida/pull/1504)
* [Developer]: Fixed race condition where FastQC file processor would start on incomplete file by filtering out files on non complete sequencing runs. [PR 1506](https://github.com/phac-nml/irida/pull/1506)

## [23.10] - 2023/10/15
* [Developer]: Added functionality to delete sequence files from file system when a sequence run is removed. [See PR 1468](https://github.com/phac-nml/irida/pull/1468)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ plugins {
}

group = "ca.corefacility.bioinformatics"
version = "23.10"
version = "23.10.1"
description = "irida"

java {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ public UIProjectMembersService(ProjectService projectService, UserService userSe
*/
public TableResponse<ProjectMemberTableModel> getProjectMembers(Long projectId, TableRequest tableRequest) {
Project project = projectService.read(projectId);

// Special case with the sort column on the name column. Front end sends "name" which is a combination of first and last name.
// Needs to get the name from the User in the ProjectUserJoin, and sort by the first name since that is what is
// displayed in the table.
if (tableRequest.getSortColumn().equals("name")) {
tableRequest.setSortColumn("user.firstName");
}

Page<Join<Project, User>> usersForProject = userService.searchUsersForProject(project, tableRequest.getSearch(),
tableRequest.getCurrent(), tableRequest.getPageSize(), tableRequest.getSort());
List<ProjectMemberTableModel> members = usersForProject.get().map(join -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ca.corefacility.bioinformatics.irida.service;

import ca.corefacility.bioinformatics.irida.model.sequenceFile.SequencingObject;
import ca.corefacility.bioinformatics.irida.model.enums.SequencingRunUploadStatus;
import ca.corefacility.bioinformatics.irida.processing.FileProcessingChain;
import ca.corefacility.bioinformatics.irida.repositories.sequencefile.SequencingObjectRepository;
import ca.corefacility.bioinformatics.irida.service.impl.processor.SequenceFileProcessorLauncher;
Expand Down Expand Up @@ -66,6 +67,12 @@ public synchronized void findFilesToProcess() {
List<SequencingObject> toProcess = sequencingObjectRepository
.getSequencingObjectsWithProcessingState(SequencingObject.ProcessingState.UNPROCESSED);

// filter out sequencing objects on a SequencingRun that is not in a COMPLETE state
toProcess.removeIf(seqObj -> (
(seqObj.getSequencingRun() != null) &&
(!seqObj.getSequencingRun().getUploadStatus().equals(SequencingRunUploadStatus.COMPLETE))
));

// individually loop through and mark the ones we're going to process. Looping individually so 2 processes are less likely to write at the same time.
Iterator<SequencingObject> iterator = toProcess.iterator();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export function PagedTable({ search = true, buttons, ...props }) {
{search ? (
<div>
<Input
className="t-search"
prefix={<IconSearch style={{ color: grey5 }} />}
onChange={(e) => onSearch(e.target.value)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export function ProjectMembersTable({ projectId }) {
},
sorter: stringSorter("name"),
defaultSortOrder: "ascend",
className: "t-user-name",
},
{
title: i18n("ProjectMembersTable.projectRole"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ const { RangePicker } = DatePicker;
* @constructor
*/
export function SamplesTable() {
const nameInputRef = React.useRef(null);
const organismInputRef = React.useRef(null);
const collectedByInputRef = React.useRef(null);
const createdInputRef = React.useRef(null);
const modifiedInputRef = React.useRef(null);

const dispatch = useDispatch();
const {
projectId,
Expand Down Expand Up @@ -115,106 +121,139 @@ export function SamplesTable() {
confirm({ closeDropdown: false });
};

function determineCurrentRef(filterName) {
return filterName === "t-organism-select"
? organismInputRef
: filterName === "t-name-select"
? nameInputRef
: filterName === "t-collectedBy-select"
? collectedByInputRef
: filterName === "t-created-filter"
? createdInputRef
: filterName === "t-modified-filter"
? modifiedInputRef
: null;
}
const getColumnSearchProps = (
dataIndex,
filterName = "",
placeholder = ""
) => ({
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
}) => (
<div style={{ padding: 8 }}>
<Select
className={filterName}
mode="tags"
placeholder={placeholder}
value={selectedKeys[0]}
onChange={(e) => {
const values = Array.isArray(e) && e.length > 0 ? [e] : e;
setSelectedKeys(values);
confirm({ closeDropdown: false });
}}
style={{ marginBottom: 8, display: "block" }}
/>
<Space>
<Button
disabled={selectedKeys.length === 0 || selectedKeys[0].length === 0}
onClick={() => handleClearSearch(clearFilters, confirm)}
size="small"
style={{ width: 89 }}
>
{i18n("Filter.clear")}
</Button>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm)}
icon={<IconSearch />}
size="small"
style={{ width: 90 }}
>
{i18n("Filter.search")}
</Button>
</Space>
</div>
),
filterIcon: (filtered) => (
<IconSearch style={{ color: filtered ? blue6 : undefined }} />
),
});

const getDateColumnSearchProps = (filterName) => ({
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
}) => (
<div style={{ padding: 8 }} className={filterName}>
<div style={{ marginBottom: 8, display: "block" }}>
<RangePicker
) => {
const currentRef = determineCurrentRef(filterName);
return {
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
setTimeout(() => currentRef.current?.focus(), 100);
}
},
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
}) => (
<div style={{ padding: 8 }}>
<Select
className={filterName}
mode="tags"
placeholder={placeholder}
value={selectedKeys[0]}
onChange={(dates) => {
if (dates !== null) {
setSelectedKeys([
[dates[0].startOf("day"), dates[1].endOf("day")],
]);
confirm({ closeDropdown: false });
} else {
handleClearSearch(clearFilters, confirm);
}
onChange={(e) => {
const values = Array.isArray(e) && e.length > 0 ? [e] : e;
setSelectedKeys(values);
confirm({ closeDropdown: false });
}}
style={{ marginBottom: 8, display: "block" }}
ref={currentRef}
/>
<Space>
<Button
disabled={
selectedKeys.length === 0 || selectedKeys[0].length === 0
}
onClick={() => handleClearSearch(clearFilters, confirm)}
size="small"
style={{ width: 89 }}
>
{i18n("Filter.clear")}
</Button>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm)}
icon={<IconSearch />}
size="small"
style={{ width: 90 }}
>
{i18n("Filter.search")}
</Button>
</Space>
</div>
<Space>
<Button
disabled={selectedKeys.length === 0}
onClick={() => handleClearSearch(clearFilters, confirm)}
size="small"
style={{ width: 89 }}
className="t-clear-btn"
>
{i18n("Filter.clear")}
</Button>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm)}
icon={<IconSearch />}
size="small"
style={{ width: 90 }}
className="t-search-btn"
>
{i18n("Filter.search")}
</Button>
</Space>
</div>
),
filterIcon: (filtered) => (
<IconSearch style={{ color: filtered ? blue6 : undefined }} />
),
});
),
filterIcon: (filtered) => (
<IconSearch style={{ color: filtered ? blue6 : undefined }} />
),
};
};

const getDateColumnSearchProps = (filterName) => {
const currentRef = determineCurrentRef(filterName);
return {
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
setTimeout(() => currentRef.current?.focus(), 100);
}
},
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
}) => (
<div style={{ padding: 8 }} className={filterName}>
<div style={{ marginBottom: 8, display: "block" }}>
<RangePicker
ref={currentRef}
value={selectedKeys[0]}
onChange={(dates) => {
if (dates !== null) {
setSelectedKeys([
[dates[0].startOf("day"), dates[1].endOf("day")],
]);
confirm({ closeDropdown: false });
} else {
handleClearSearch(clearFilters, confirm);
}
}}
/>
</div>
<Space>
<Button
disabled={selectedKeys.length === 0}
onClick={() => handleClearSearch(clearFilters, confirm)}
size="small"
style={{ width: 89 }}
className="t-clear-btn"
>
{i18n("Filter.clear")}
</Button>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm)}
icon={<IconSearch />}
size="small"
style={{ width: 90 }}
className="t-search-btn"
>
{i18n("Filter.search")}
</Button>
</Space>
</div>
),
filterIcon: (filtered) => (
<IconSearch style={{ color: filtered ? blue6 : undefined }} />
),
};
};

const columns = [
{
Expand Down Expand Up @@ -298,7 +337,10 @@ export function SamplesTable() {
title: i18n("SamplesTable.Column.collectedBy"),
dataIndex: ["sample", "collectedBy"],
sorter: true,
...getColumnSearchProps(["sample", "collectedBy"]),
...getColumnSearchProps(
["sample", "collectedBy"],
"t-collectedBy-select"
),
},
{
title: i18n("SamplesTable.Column.created"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.stream.Collectors;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
Expand All @@ -29,6 +30,15 @@ public class AntTable {
@FindBy(className = "ant-table-row")
List<WebElement> rows;

@FindBy(css = ".ant-pagination-next button")
WebElement nextButton;

@FindBy(css = ".ant-pagination-prev button")
WebElement prevButton;

@FindBy(css = ".t-search input")
WebElement searchInput;

public static AntTable getTable(WebDriver driver) {
return PageFactory.initElements(driver, AntTable.class);
}
Expand Down Expand Up @@ -89,4 +99,19 @@ private Long getMillisecondsFromDate(String dateStr, DateFormat dateFormat) {
}
}

public void goToNextPage() {
nextButton.click();
}

public void goToPrevPage() {
prevButton.click();
}

public void search(String text) {
if (!Strings.isNullOrEmpty(text)) {
searchInput.sendKeys(Keys.chord(Keys.CONTROL, "a"), text, Keys.ENTER);
} else {
searchInput.sendKeys(Keys.chord(Keys.CONTROL, "a"), Keys.BACK_SPACE, Keys.ENTER);
}
}
}
Loading

0 comments on commit 6bc942e

Please sign in to comment.