diff --git a/src/app/features/collections/components/add-to-collection/select-project-step/select-project-step.component.html b/src/app/features/collections/components/add-to-collection/select-project-step/select-project-step.component.html
index a17d3deab..ceae12d81 100644
--- a/src/app/features/collections/components/add-to-collection/select-project-step/select-project-step.component.html
+++ b/src/app/features/collections/components/add-to-collection/select-project-step/select-project-step.component.html
@@ -26,6 +26,7 @@
{{ 'collections.addToCollection.selectProject' | translate }}
+ ({ id, title: `Project ${id}`, isPublic }) as ProjectModel;
+
describe('ProjectSelectorComponent', () => {
let component: ProjectSelectorComponent;
let fixture: ComponentFixture;
+ let store: Store;
beforeEach(() => {
TestBed.configureTestingModule({
@@ -22,6 +27,7 @@ describe('ProjectSelectorComponent', () => {
providers: [provideOSFCore(), MockProvider(ToastService), provideStore([ProjectsState, UserState])],
});
+ store = TestBed.inject(Store);
fixture = TestBed.createComponent(ProjectSelectorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
@@ -51,4 +57,36 @@ describe('ProjectSelectorComponent', () => {
expect(mockEvent.originalEvent.preventDefault).toHaveBeenCalled();
});
+
+ describe('publicOnly filtering', () => {
+ const publicProject = makeProject('1', true);
+ const privateProject = makeProject('2', false);
+
+ const setProjects = (projects: ProjectModel[]) => {
+ store.reset({
+ ...store.snapshot(),
+ projects: { projects: { data: projects, isLoading: false, error: null } },
+ });
+ };
+
+ it('should show all projects when publicOnly is false', () => {
+ fixture.componentRef.setInput('publicOnly', false);
+ setProjects([publicProject, privateProject]);
+ fixture.detectChanges();
+
+ const ids = component.projectsOptions().map((o) => o.value.id);
+ expect(ids).toContain('1');
+ expect(ids).toContain('2');
+ });
+
+ it('should only show public projects when publicOnly is true', () => {
+ fixture.componentRef.setInput('publicOnly', true);
+ setProjects([publicProject, privateProject]);
+ fixture.detectChanges();
+
+ const ids = component.projectsOptions().map((o) => o.value.id);
+ expect(ids).toContain('1');
+ expect(ids).not.toContain('2');
+ });
+ });
});
diff --git a/src/app/shared/components/project-selector/project-selector.component.ts b/src/app/shared/components/project-selector/project-selector.component.ts
index 5cd711e0f..2b7597ec8 100644
--- a/src/app/shared/components/project-selector/project-selector.component.ts
+++ b/src/app/shared/components/project-selector/project-selector.component.ts
@@ -44,6 +44,7 @@ export class ProjectSelectorComponent {
placeholder = input('common.buttons.select');
showClear = input(true);
excludeProjectIds = input([]);
+ publicOnly = input(false);
selectedProject = model(null);
projectChange = output();
@@ -105,7 +106,9 @@ export class ProjectSelectorComponent {
}
const excludeSet = new Set(excludeIds);
- const availableProjects = projects.filter((project) => !excludeSet.has(project.id));
+ const availableProjects = projects.filter(
+ (project) => !excludeSet.has(project.id) && (!this.publicOnly() || project.isPublic)
+ );
const options = availableProjects.map((project) => ({
label: project.title,
@@ -132,6 +135,10 @@ export class ProjectSelectorComponent {
'filter[current_user_permissions]': 'admin',
};
+ if (this.publicOnly()) {
+ params['filter[public]'] = 'true';
+ }
+
if (filterTitle && filterTitle.trim()) {
params['filter[title]'] = filterTitle;
}