Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import { NgOptimizedImage } from '@angular/common';
import { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core';
import { ActivatedRoute, Router, RouterOutlet } from '@angular/router';

import { resourceTabOptions } from '@osf/features/admin-institutions/constants/resource-tab-option.constant';
import { Primitive } from '@osf/shared/helpers';
import { FetchInstitutionById, InstitutionsSearchSelectors } from '@osf/shared/stores';
import { LoadingSpinnerComponent, SelectComponent } from '@shared/components';
import { FetchInstitutionById, InstitutionsSearchSelectors } from '@shared/stores';

import { resourceTabOptions } from './constants';
import { AdminInstitutionResourceTab } from './enums';

@Component({
selector: 'osf-admin-institutions',
Expand All @@ -31,9 +33,8 @@ export class AdminInstitutionsComponent implements OnInit {
fetchInstitution: FetchInstitutionById,
});

selectedTab = 'summary';

resourceTabOptions = resourceTabOptions;
selectedTab = AdminInstitutionResourceTab.Summary;

ngOnInit() {
const institutionId = this.route.snapshot.params['institution-id'];
Expand All @@ -42,16 +43,17 @@ export class AdminInstitutionsComponent implements OnInit {
this.actions.fetchInstitution(institutionId);
}

this.selectedTab = this.route.snapshot.firstChild?.routeConfig?.path || 'summary';
this.selectedTab =
(this.route.snapshot.firstChild?.routeConfig?.path as AdminInstitutionResourceTab) ||
AdminInstitutionResourceTab.Summary;
}

onTabChange(selectedValue: Primitive) {
const value = String(selectedValue);
const value = selectedValue as AdminInstitutionResourceTab;
this.selectedTab = value;
const selectedTab = this.resourceTabOptions.find((tab) => tab.value === value);

if (selectedTab) {
this.router.navigate([selectedTab.value], { relativeTo: this.route });
if (this.selectedTab) {
this.router.navigate([this.selectedTab], { relativeTo: this.route });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
<ng-content select="[slot=amount]"></ng-content>
</div>

<p-menu #downloadMenu [model]="downloadMenuItems()" appendTo="body" popup>
<p-menu #downloadMenu [model]="downloadMenuItems" appendTo="body" popup>
<ng-template #item let-item>
<a class="p-menu-item-link ml-1" osfStopPropagation target="_blank" [href]="item.link">
<a
class="p-menu-item-link ml-1"
osfStopPropagation
(click)="downloadClicked.emit(item.value)"
(keydown.enter)="downloadClicked.emit(item.value)"
tabindex="0"
>
<i [class]="item.icon"></i>

{{ item.label }}
Expand Down Expand Up @@ -39,15 +45,13 @@
</ng-template>
</p-multiselect>

@if (downloadLink()) {
<p-button
icon="fa fa-download text-primary text-xl"
outlined
class="grey-border-color download-button"
severity="info"
(click)="downloadMenu.toggle($event)"
/>
}
<p-button
icon="fa fa-download text-primary text-xl"
outlined
class="grey-border-color download-button"
severity="info"
(click)="downloadMenu.toggle($event)"
/>

@if (reportsLink()) {
<a
Expand Down Expand Up @@ -131,6 +135,12 @@
}
</tr>
</ng-template>

<ng-template pTemplate="emptymessage">
<tr>
<td colspan="15" class="text-center">{{ 'adminInstitutions.institutionUsers.noData' | translate }}</td>
</tr>
</ng-template>
</p-table>

@if (isNextPreviousPagination()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import {
} from '@osf/features/admin-institutions/models';
import { CustomPaginatorComponent } from '@osf/shared/components';
import { StopPropagationDirective } from '@shared/directives';
import { SortOrder } from '@shared/enums';
import { QueryParams } from '@shared/models';

import { DOWNLOAD_OPTIONS } from '../../constants';
import { DownloadType } from '../../enums';

@Component({
selector: 'osf-admin-table',
imports: [
Expand Down Expand Up @@ -75,34 +77,13 @@ export class AdminTableComponent {
sortChanged = output<QueryParams>();
iconClicked = output<TableIconClickEvent>();
linkPageChanged = output<string>();
downloadClicked = output<DownloadType>();

downloadLink = input<string>('');
reportsLink = input<string>('');
reportsLink = input<string | undefined>('');

selectedColumns = signal<TableColumn[]>([]);

downloadMenuItems = computed(() => {
const baseUrl = this.downloadLink();
if (!baseUrl) return [];

return [
{
label: 'CSV',
icon: 'fa fa-file-csv',
link: this.createUrl(baseUrl, 'text/csv'),
},
{
label: 'TSV',
icon: 'fa fa-file-alt',
link: this.createUrl(baseUrl, 'text/tab-separated-values'),
},
{
label: 'JSON',
icon: 'fa fa-file-code',
link: this.createUrl(baseUrl, 'application/json'),
},
];
});
downloadMenuItems = DOWNLOAD_OPTIONS;

selectedColumnsComputed = computed(() => {
const selected = this.selectedColumns();
Expand Down Expand Up @@ -149,9 +130,10 @@ export class AdminTableComponent {
if (event.field && this.userInitiatedSort) {
this.sortChanged.emit({
sortColumn: event.field,
sortOrder: event.order === -1 ? SortOrder.Desc : SortOrder.Asc,
sortOrder: event.order,
} as QueryParams);
}

this.userInitiatedSort = false;
}

Expand Down Expand Up @@ -180,10 +162,6 @@ export class AdminTableComponent {
this.linkPageChanged.emit(link);
}

private createUrl(baseUrl: string, mediaType: string): string {
return `${baseUrl}&acceptMediatype=${encodeURIComponent(mediaType)}`;
}

getLinkUrl(value: string | number | TableCellLink | undefined): string {
if (this.isLink(value)) {
return value.url;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { SelectOption } from '@shared/models';

import { ContactOption } from '../enums';

export const CONTACT_OPTIONS: SelectOption[] = [
{ label: 'adminInstitutions.contact.requestAccess', value: ContactOption.RequestAccess },
{ label: 'adminInstitutions.contact.sendMessage', value: ContactOption.SendMessage },
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { DownloadType } from '../enums';

export const DOWNLOAD_FORMATS: Record<DownloadType, string> = {
[DownloadType.CSV]: 'text/csv',
[DownloadType.TSV]: 'text/tab-separated-values',
[DownloadType.JSON]: 'application/json',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { DownloadType } from '../enums';

export const DOWNLOAD_OPTIONS = [
{
value: DownloadType.CSV,
label: 'CSV',
icon: 'fa fa-file-csv',
},
{
value: DownloadType.TSV,
label: 'TSV',
icon: 'fa fa-file-alt',
},
{
value: DownloadType.JSON,
label: 'JSON',
icon: 'fa fa-file-code',
},
];
5 changes: 4 additions & 1 deletion src/app/features/admin-institutions/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
export * from './admin-table-columns.constant';
export * from './contact-options.constant';
export * from './department-options.constant';
export * from './download-formats.constant';
export * from './download-options.constant';
export * from './preprints-table-columns.constant';
export * from './project-table-columns.constant';
export * from './registration-table-columns.constant';
export * from './resource-tab-option.constant';
export * from './user-table-columns.constant';
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export const projectTableColumns: TableColumn[] = [
sortable: true,
isLink: true,
linkTarget: '_blank',
showIcon: true,
iconClass: 'fa-solid fa-comment text-primary',
iconTooltip: 'adminInstitutions.institutionUsers.sendMessage',
iconAction: 'sendMessage',
},
{
field: 'views',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { CustomOption } from '@shared/models';

export const resourceTabOptions: CustomOption<string>[] = [
{ label: 'adminInstitutions.summary.title', value: 'summary' },
{ label: 'common.search.tabs.users', value: 'users' },
{ label: 'common.search.tabs.projects', value: 'projects' },
{ label: 'common.search.tabs.registrations', value: 'registrations' },
{ label: 'common.search.tabs.preprints', value: 'preprints' },
import { AdminInstitutionResourceTab } from '../enums';

export const resourceTabOptions: CustomOption<AdminInstitutionResourceTab>[] = [
{ label: 'adminInstitutions.summary.title', value: AdminInstitutionResourceTab.Summary },
{ label: 'common.search.tabs.users', value: AdminInstitutionResourceTab.Users },
{ label: 'common.search.tabs.projects', value: AdminInstitutionResourceTab.Projects },
{ label: 'common.search.tabs.registrations', value: AdminInstitutionResourceTab.Registrations },
{ label: 'common.search.tabs.preprints', value: AdminInstitutionResourceTab.Preprints },
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<div class="contact-dialog">
<p-selectButton
class="w-full"
styleClass="w-full"
[options]="contactOptions"
[ngModel]="selectedOption()"
(ngModelChange)="onOptionChange($event)"
optionLabel="label"
optionValue="value"
[unselectable]="true"
>
<ng-template #item let-item>
{{ item.label | translate }}
</ng-template>
</p-selectButton>

<form [formGroup]="form" class="mt-4">
@if (isRequestAccess) {
<p>{{ 'adminInstitutions.contact.message' | translate }}</p>

<div class="flex flex-column gap-3 mt-3">
<div class="flex items-center gap-2">
<p-radiobutton
[value]="projectPermission.Administrative"
formControlName="permission"
inputId="permission1"
/>
<label for="permission1" class="font-bold">
{{ 'adminInstitutions.contact.administrative' | translate }}
</label>
</div>

<div class="flex items-center gap-2">
<p-radiobutton [value]="projectPermission.Write" formControlName="permission" inputId="permission2" />
<label for="permission2" class="font-bold">{{ 'adminInstitutions.contact.readWrite' | translate }}</label>
</div>
</div>
}

<div class="flex flex-column gap-2 mt-3">
<textarea
pTextarea
formControlName="emailContent"
[placeholder]="'adminInstitutions.institutionUsers.writeEmailText' | translate"
[rows]="6"
[style]="{ 'min-height': '200px' }"
></textarea>
</div>

<div class="flex flex-column gap-1 mt-3">
<span>{{ 'adminInstitutions.institutionUsers.sincerelyYours' | translate }}, </span>
<span>{{ config.data }}</span>
</div>

@if (!isRequestAccess) {
<div class="flex flex-column gap-3 mt-3">
<div class="flex align-items-center gap-2">
<p-checkbox formControlName="ccSender" binary="true" inputId="cc-sender"></p-checkbox>
<label for="cc-sender" class="m-0 font-bold font-medium cursor-pointer">
{{ 'adminInstitutions.institutionUsers.ccSender' | translate }}
</label>
</div>

<div class="flex align-items-center gap-2">
<p-checkbox formControlName="allowReplyToSender" binary="true" inputId="allow-reply"></p-checkbox>
<label for="allow-reply" class="m-0 font-bold font-medium cursor-pointer">
{{ 'adminInstitutions.institutionUsers.allowReplyToSenderAddress' | translate }}
</label>
</div>
</div>
}
</form>

<div class="flex justify-content-between gap-2 mt-4">
<p-button
class="w-full"
styleClass="w-full"
severity="info"
[label]="'common.buttons.cancel' | translate"
(click)="onCancel()"
/>
<p-button
class="w-full"
styleClass="w-full"
[label]="'common.buttons.send' | translate"
(click)="onSend()"
[disabled]="!form.valid"
/>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ContactDialogComponent } from './contact-dialog.component';

describe('ContactDialogComponent', () => {
let component: ContactDialogComponent;
let fixture: ComponentFixture<ContactDialogComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ContactDialogComponent],
}).compileComponents();

fixture = TestBed.createComponent(ContactDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Loading