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; }