diff --git a/src/app/features/project/metadata/components/index.ts b/src/app/features/project/metadata/components/index.ts index 94ba6321d..252fe9593 100644 --- a/src/app/features/project/metadata/components/index.ts +++ b/src/app/features/project/metadata/components/index.ts @@ -7,4 +7,3 @@ export { ProjectMetadataLicenseComponent } from './project-metadata-license/proj export { ProjectMetadataPublicationDoiComponent } from './project-metadata-publication-doi/project-metadata-publication-doi.component'; export { ProjectMetadataResourceInformationComponent } from './project-metadata-resource-information/project-metadata-resource-information.component'; export { ProjectMetadataSubjectsComponent } from './project-metadata-subjects/project-metadata-subjects.component'; -export { ProjectMetadataTagsComponent } from './project-metadata-tags/project-metadata-tags.component'; diff --git a/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.html b/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.html deleted file mode 100644 index e50cf5d6d..000000000 --- a/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.html +++ /dev/null @@ -1,16 +0,0 @@ - - - {{ 'project.overview.metadata.tags' | translate }} - - - - - diff --git a/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.scss b/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.scss deleted file mode 100644 index b080985ce..000000000 --- a/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.scss +++ /dev/null @@ -1,183 +0,0 @@ -.removable-chip { - transition: all 0.2s ease; - - &:hover { - transform: scale(0.95); - opacity: 0.8; - } - - &::after { - content: " ×"; - font-weight: bold; - margin-left: 4px; - } -} - -.tags-input-container { - position: relative; -} - -.tags-input-field { - &:focus-within { - border-color: var(--p-primary-color) !important; - box-shadow: 0 0 0 1px var(--p-primary-color); - } -} - -.tag-input { - min-width: 120px; - background: transparent; - font-size: 0.875rem; - - &::placeholder { - color: var(--p-text-muted-color); - } - - &:focus { - outline: none; - } -} - -.suggestions-dropdown { - position: absolute; - z-index: 1000; - margin-top: 0.25rem; - width: 100%; - border: 1px solid var(--p-border-color); - border-radius: 4px; - background: white; - box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); - max-height: 200px; - overflow-y: auto; -} - -.suggestion-item { - padding: 0.5rem; - cursor: pointer; - transition: background-color 0.2s ease; - - &:hover, - &:focus { - background-color: #f3f4f6; - } -} - -::ng-deep .p-chips { - .p-chips-multiple-container { - min-height: 80px; - padding: 12px; - border-radius: 6px; - border: 1px solid var(--p-border-color); - background: var(--p-surface-0); - - &:focus-within { - border-color: var(--p-primary-color); - box-shadow: 0 0 0 1px var(--p-primary-color); - } - } - - .p-chips-token { - background: var(--p-primary-50); - color: var(--p-primary-700); - border: 1px solid var(--p-primary-200); - border-radius: 16px; - padding: 4px 8px; - margin: 2px; - font-size: 0.875rem; - - .p-chips-token-label { - padding: 0 4px; - } - - .p-chips-token-icon { - margin-left: 4px; - width: auto; - height: auto; - background: none; - border: none; - color: var(--p-primary-600); - font-size: 12px; - - &:hover { - color: var(--p-red-600); - } - } - } - - .p-chips-input-token { - flex: 1; - - input { - border: none; - outline: none; - background: transparent; - padding: 4px; - font-size: 0.875rem; - width: 100%; - - &::placeholder { - color: var(--p-text-muted-color); - } - } - } -} - -::ng-deep .tag-autocomplete { - .p-autocomplete-multiple-container { - min-height: 80px; - padding: 12px; - border-radius: 6px; - border: 1px solid var(--p-border-color); - background: var(--p-surface-0); - - &:focus-within { - border-color: var(--p-primary-color); - box-shadow: 0 0 0 1px var(--p-primary-color); - } - } - - .p-autocomplete-token { - background: var(--p-primary-50); - color: var(--p-primary-700); - border: 1px solid var(--p-primary-200); - border-radius: 16px; - padding: 4px 8px; - margin: 2px; - font-size: 0.875rem; - - .p-autocomplete-token-label { - padding: 0 4px; - } - - .p-autocomplete-token-icon { - margin-left: 4px; - width: auto; - height: auto; - background: none; - border: none; - color: var(--p-primary-600); - font-size: 12px; - - &:hover { - color: var(--p-red-600); - } - } - } - - .p-autocomplete-input-token { - flex: 1; - - input { - border: none; - outline: none; - background: transparent; - padding: 4px; - font-size: 0.875rem; - width: 100%; - - &::placeholder { - color: var(--p-text-muted-color); - } - } - } -} diff --git a/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.spec.ts b/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.spec.ts deleted file mode 100644 index d0431dac4..000000000 --- a/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ProjectMetadataTagsComponent } from './project-metadata-tags.component'; - -describe('ProjectMetadataTagsComponent', () => { - let component: ProjectMetadataTagsComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ProjectMetadataTagsComponent], - }).compileComponents(); - - fixture = TestBed.createComponent(ProjectMetadataTagsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.ts b/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.ts deleted file mode 100644 index 099bd2596..000000000 --- a/src/app/features/project/metadata/components/project-metadata-tags/project-metadata-tags.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { TranslatePipe } from '@ngx-translate/core'; - -import { Card } from 'primeng/card'; -import { Chips } from 'primeng/chips'; - -import { ChangeDetectionStrategy, Component, effect, input, output, signal } from '@angular/core'; -import { FormsModule } from '@angular/forms'; - -import { ProjectOverview } from '@osf/features/project/overview/models'; - -@Component({ - selector: 'osf-project-metadata-tags', - imports: [Card, TranslatePipe, FormsModule, Chips], - templateUrl: './project-metadata-tags.component.html', - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ProjectMetadataTagsComponent { - tagsChanged = output(); - - currentProject = input.required(); - - currentTags = signal([]); - suggestedTags = signal([]); - - constructor() { - effect(() => { - const project = this.currentProject(); - this.currentTags.set(project ? project.tags || [] : []); - }); - } - - onTagsChange(tags: string[]): void { - this.currentTags.set(tags); - this.tagsChanged.emit(tags); - } - - searchTags(event: { query: string }): void { - this.suggestedTags.set([...this.suggestedTags(), event.query]); - } -} diff --git a/src/app/features/project/metadata/project-metadata.component.html b/src/app/features/project/metadata/project-metadata.component.html index 95b1ada90..43596d5fe 100644 --- a/src/app/features/project/metadata/project-metadata.component.html +++ b/src/app/features/project/metadata/project-metadata.component.html @@ -92,10 +92,16 @@ [currentProject]="currentProject()" /> - + + + {{ 'project.overview.metadata.tags' | translate }} + + + + + + diff --git a/src/app/shared/components/tags-input/tags-input.component.scss b/src/app/shared/components/tags-input/tags-input.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/shared/components/tags-input/tags-input.component.spec.ts b/src/app/shared/components/tags-input/tags-input.component.spec.ts new file mode 100644 index 000000000..ea0ed8657 --- /dev/null +++ b/src/app/shared/components/tags-input/tags-input.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TagsInputComponent } from './tags-input.component'; + +describe('TagsInputComponent', () => { + let component: TagsInputComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TagsInputComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(TagsInputComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/tags-input/tags-input.component.ts b/src/app/shared/components/tags-input/tags-input.component.ts new file mode 100644 index 000000000..e81fd8eea --- /dev/null +++ b/src/app/shared/components/tags-input/tags-input.component.ts @@ -0,0 +1,22 @@ +import { TranslatePipe } from '@ngx-translate/core'; + +import { Chips } from 'primeng/chips'; + +import { ChangeDetectionStrategy, Component, input, output } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'osf-tags-input', + imports: [TranslatePipe, FormsModule, Chips], + templateUrl: './tags-input.component.html', + styleUrl: './tags-input.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TagsInputComponent { + tags = input([]); + tagsChanged = output(); + + onTagsChange(tags: string[]): void { + this.tagsChanged.emit(tags); + } +} diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 761709881..2ab43f0cd 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -43,6 +43,9 @@ "deleteConfirmation": { "header": "Delete", "message": "Are you sure you want to proceed?" + }, + "placeholder": { + "addTag": "Add tags" } }, "navigation": { diff --git a/src/assets/styles/overrides/chip.scss b/src/assets/styles/overrides/chip.scss index f2741562d..38b406ab7 100644 --- a/src/assets/styles/overrides/chip.scss +++ b/src/assets/styles/overrides/chip.scss @@ -31,7 +31,3 @@ margin-top: 2px; } } - -.tag-chips { - --p-inputchips-focus-border-color: var(--p-surface-300); -}