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
9 changes: 5 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module.exports = {
'src/app/**/*.{ts,js}',
'!src/app/app.config.ts',
'!src/app/**/*.routes.{ts.js}',
'!src/app/**/*.actions.{ts.js}',
'!src/app/**/*.models.{ts.js}',
'!src/app/**/*.model.{ts.js}',
'!src/app/**/*.route.{ts,js}',
Expand All @@ -45,10 +46,10 @@ module.exports = {
extensionsToTreatAsEsm: ['.ts'],
coverageThreshold: {
global: {
branches: 14.15,
functions: 14.83,
lines: 41.15,
statements: 41.63,
branches: 14.27,
functions: 15.55,
lines: 42.6,
statements: 43.2,
},
},
watchPathIgnorePatterns: [
Expand Down
4 changes: 2 additions & 2 deletions src/app/features/files/pages/files/files.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
SearchInputComponent,
SubHeaderComponent,
} from '@shared/components';
import { ConfiguredStorageAddon, FilesTreeActions, OsfFile } from '@shared/models';
import { ConfiguredStorageAddonModel, FilesTreeActions, OsfFile } from '@shared/models';
import { FilesService } from '@shared/services';

import { CreateFolderDialogComponent } from '../../components';
Expand Down Expand Up @@ -346,7 +346,7 @@ export class FilesComponent {
this.router.navigate([file.guid], { relativeTo: this.activeRoute });
}

getAddonName(addons: ConfiguredStorageAddon[], provider: string): string {
getAddonName(addons: ConfiguredStorageAddonModel[], provider: string): string {
if (provider === 'osfstorage') {
return 'Osf Storage';
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/app/features/files/store/files.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ContributorModel, OsfFile, ResourceMetadata } from '@shared/models';
import { ConfiguredStorageAddon } from '@shared/models/addons';
import { ConfiguredStorageAddonModel } from '@shared/models/addons';
import { AsyncStateModel } from '@shared/models/store';

import { FileProvider } from '../constants';
Expand All @@ -20,7 +20,7 @@ export interface FilesStateModel {
fileRevisions: AsyncStateModel<OsfFileRevision[] | null>;
tags: AsyncStateModel<string[]>;
rootFolders: AsyncStateModel<OsfFile[] | null>;
configuredStorageAddons: AsyncStateModel<ConfiguredStorageAddon[] | null>;
configuredStorageAddons: AsyncStateModel<ConfiguredStorageAddonModel[] | null>;
}

export const filesStateDefaults: FilesStateModel = {
Expand Down
4 changes: 2 additions & 2 deletions src/app/features/files/store/files.selectors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Selector } from '@ngxs/store';

import { ConfiguredStorageAddon, ContributorModel, OsfFile, ResourceMetadata } from '@shared/models';
import { ConfiguredStorageAddonModel, ContributorModel, OsfFile, ResourceMetadata } from '@shared/models';

import { OsfFileCustomMetadata, OsfFileRevision } from '../models';

Expand Down Expand Up @@ -114,7 +114,7 @@ export class FilesSelectors {
}

@Selector([FilesState])
static getConfiguredStorageAddons(state: FilesStateModel): ConfiguredStorageAddon[] | null {
static getConfiguredStorageAddons(state: FilesStateModel): ConfiguredStorageAddonModel[] | null {
return state.configuredStorageAddons.data;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ <h2 class="align-self-center">
(keydown.enter)="toggleEditMode()"
></p-button>
</div>
<!-- @if (storageAddon()) {
<p class="text-lg">
{{ storageAddon()?.wbKey }}
</p>
} @else { -->
<osf-folder-selector
[accountName]="addon()?.displayName || ''"
[operationInvocationResult]="operationInvocation()?.operationResult || []"
Expand All @@ -72,6 +77,7 @@ <h2 class="align-self-center">
(save)="handleUpdateAddonConfiguration()"
(cancelSelection)="toggleEditMode()"
/>
<!-- } -->
</section>
}
</section>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createDispatchMap, select } from '@ngxs/store';
import { createDispatchMap, select, Store } from '@ngxs/store';

import { TranslatePipe } from '@ngx-translate/core';

Expand All @@ -25,7 +25,7 @@ import { OperationNames } from '@osf/features/project/addons/enums';
import { getAddonTypeString } from '@osf/shared/helpers';
import { SubHeaderComponent } from '@shared/components';
import { FolderSelectorComponent } from '@shared/components/addons/folder-selector/folder-selector.component';
import { ConfiguredAddon } from '@shared/models';
import { AddonModel, ConfiguredStorageAddonModel } from '@shared/models';
import { AddonDialogService, AddonFormService, AddonOperationInvocationService, ToastService } from '@shared/services';
import {
AddonsSelectors,
Expand Down Expand Up @@ -63,9 +63,26 @@ export class ConfigureAddonComponent implements OnInit {
private addonDialogService = inject(AddonDialogService);
private addonFormService = inject(AddonFormService);
private operationInvocationService = inject(AddonOperationInvocationService);

/**
* Injected NGXS store used to access and dispatch state actions and selectors.
*/
private store = inject(Store);

/**
* Form control for capturing or displaying the user’s selected account name.
*/
protected accountNameControl = new FormControl('');
protected addon = signal<ConfiguredAddon | null>(null);
/**
* Signal representing the currently selected `Addon` from the list of available storage addons.
* This value updates reactively as the selection changes.
*/
protected storageAddon = signal<AddonModel | undefined>(undefined);
/**
* Signal representing the currently selected and configured storage addon model.
* This may be `null` if no addon has been configured.
*/
protected addon = signal<ConfiguredStorageAddonModel | null>(null);

protected isEditMode = signal<boolean>(false);
protected selectedRootFolderId = signal('');
protected addonsUserReference = select(AddonsSelectors.getAddonsUserReference);
Expand Down Expand Up @@ -101,9 +118,15 @@ export class ConfigureAddonComponent implements OnInit {
}

private initializeAddon(): void {
const addon = this.router.getCurrentNavigation()?.extras.state?.['addon'] as ConfiguredAddon;
const addon = this.router.getCurrentNavigation()?.extras.state?.['addon'] as ConfiguredStorageAddonModel;

if (addon) {
this.storageAddon.set(
this.store.selectSnapshot((state) =>
AddonsSelectors.getStorageAddon(state.addons, addon.externalStorageServiceId || '')
)
);

this.addon.set(addon);
this.selectedRootFolderId.set(addon.selectedFolderId);
this.accountNameControl.setValue(addon.displayName);
Expand Down Expand Up @@ -132,7 +155,7 @@ export class ConfigureAddonComponent implements OnInit {
this.openDisconnectDialog(currentAddon);
}

private openDisconnectDialog(addon: ConfiguredAddon): void {
private openDisconnectDialog(addon: ConfiguredStorageAddonModel): void {
const dialogRef = this.addonDialogService.openDisconnectDialog(addon);

dialogRef.subscribe((result) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ActivatedRoute, Navigation, Router, UrlTree } from '@angular/router';

import { SubHeaderComponent } from '@osf/shared/components';
import { CredentialsFormat } from '@shared/enums';
import { Addon } from '@shared/models';
import { AddonModel } from '@shared/models';
import { AddonsSelectors } from '@shared/stores/addons';

import { ConnectConfiguredAddonComponent } from './connect-configured-addon.component';
Expand All @@ -20,7 +20,7 @@ describe('ConnectAddonComponent', () => {
let component: ConnectConfiguredAddonComponent;
let fixture: ComponentFixture<ConnectConfiguredAddonComponent>;

const mockAddon: Addon = {
const mockAddon: AddonModel = {
id: 'test-addon-id',
type: 'external-storage-services',
displayName: 'Test Addon',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
AddonTermsComponent,
FolderSelectorComponent,
} from '@shared/components/addons';
import { Addon, AddonTerm, AuthorizedAddon, AuthorizedAddonRequestJsonApi } from '@shared/models';
import { AddonModel, AddonTerm, AuthorizedAddon, AuthorizedAddonRequestJsonApi } from '@shared/models';
import { AddonDialogService, AddonFormService, AddonOperationInvocationService, ToastService } from '@shared/services';
import {
AddonsSelectors,
Expand Down Expand Up @@ -74,7 +74,7 @@ export class ConnectConfiguredAddonComponent {
protected readonly stepper = viewChild(Stepper);
protected accountNameControl = new FormControl('');
protected terms = signal<AddonTerm[]>([]);
protected addon = signal<Addon | AuthorizedAddon | null>(null);
protected addon = signal<AddonModel | AuthorizedAddon | null>(null);
protected addonAuthUrl = signal<string>('/settings/addons');
protected currentAuthorizedAddonAccounts = signal<AuthorizedAddon[]>([]);
protected chosenAccountId = signal('');
Expand Down Expand Up @@ -128,7 +128,7 @@ export class ConnectConfiguredAddonComponent {
});

constructor() {
const addon = this.router.getCurrentNavigation()?.extras.state?.['addon'] as Addon | AuthorizedAddon;
const addon = this.router.getCurrentNavigation()?.extras.state?.['addon'] as AddonModel | AuthorizedAddon;
if (!addon) {
this.router.navigate([`${this.baseUrl()}/addons`]);
}
Expand Down Expand Up @@ -243,7 +243,7 @@ export class ConnectConfiguredAddonComponent {

private processAuthorizedAddons(
addonConfig: AddonConfigMap[keyof AddonConfigMap],
currentAddon: Addon | AuthorizedAddon
currentAddon: AddonModel | AuthorizedAddon
) {
const authorizedAddons = addonConfig.getAuthorizedAddons();
const matchingAddons = this.findMatchingAddons(authorizedAddons, currentAddon);
Expand All @@ -262,7 +262,7 @@ export class ConnectConfiguredAddonComponent {

private findMatchingAddons(
authorizedAddons: AuthorizedAddon[],
currentAddon: Addon | AuthorizedAddon
currentAddon: AddonModel | AuthorizedAddon
): AuthorizedAddon[] {
return authorizedAddons.filter((addon) => addon.externalServiceName === currentAddon.externalServiceName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { SubHeaderComponent } from '@osf/shared/components';
import { ProjectAddonsStepperValue } from '@osf/shared/enums';
import { getAddonTypeString, isAuthorizedAddon } from '@osf/shared/helpers';
import { AddonSetupAccountFormComponent, AddonTermsComponent } from '@shared/components/addons';
import { Addon, AddonTerm, AuthorizedAddon, AuthorizedAddonRequestJsonApi } from '@shared/models';
import { AddonModel, AddonTerm, AuthorizedAddon, AuthorizedAddonRequestJsonApi } from '@shared/models';
import { AddonsSelectors, CreateAuthorizedAddon, UpdateAuthorizedAddon } from '@shared/stores/addons';

@Component({
Expand Down Expand Up @@ -43,7 +43,7 @@ export class ConnectAddonComponent {
protected readonly ProjectAddonsStepperValue = ProjectAddonsStepperValue;

protected terms = signal<AddonTerm[]>([]);
protected addon = signal<Addon | AuthorizedAddon | null>(null);
protected addon = signal<AddonModel | AuthorizedAddon | null>(null);
protected addonAuthUrl = signal<string>('/settings/addons');

protected addonsUserReference = select(AddonsSelectors.getAddonsUserReference);
Expand All @@ -70,7 +70,7 @@ export class ConnectAddonComponent {
});

constructor() {
const addon = this.router.getCurrentNavigation()?.extras.state?.['addon'] as Addon | AuthorizedAddon;
const addon = this.router.getCurrentNavigation()?.extras.state?.['addon'] as AddonModel | AuthorizedAddon;
if (!addon) {
this.router.navigate([`${this.baseUrl()}/addons`]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { TranslatePipe } from '@ngx-translate/core';
import { Component, input } from '@angular/core';

import { AddonCardComponent } from '@shared/components/addons';
import { Addon, AuthorizedAddon, ConfiguredAddon } from '@shared/models';
import { AddonModel, AuthorizedAddon, ConfiguredStorageAddonModel } from '@shared/models';

@Component({
selector: 'osf-addon-card-list',
Expand All @@ -12,7 +12,7 @@ import { Addon, AuthorizedAddon, ConfiguredAddon } from '@shared/models';
styleUrl: './addon-card-list.component.scss',
})
export class AddonCardListComponent {
cards = input<(Addon | AuthorizedAddon | ConfiguredAddon)[]>([]);
cards = input<(AddonModel | AuthorizedAddon | ConfiguredStorageAddonModel)[]>([]);
cardButtonLabel = input<string>('');
showDangerButton = input<boolean>(false);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Router } from '@angular/router';

import { CredentialsFormat } from '@shared/enums';
import { MockCustomConfirmationServiceProvider } from '@shared/mocks';
import { Addon } from '@shared/models';
import { AddonModel } from '@shared/models';
import { CustomConfirmationService } from '@shared/services';

import { AddonCardComponent } from './addon-card.component';
Expand All @@ -22,7 +22,7 @@ describe('AddonCardComponent', () => {
let customConfirmationService: CustomConfirmationService;
let store: Store;

const mockAddon: Addon = {
const mockAddon: AddonModel = {
id: 'test-addon-id',
type: 'external-storage-services',
displayName: 'Test Addon',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Router } from '@angular/router';

import { getAddonTypeString, isConfiguredAddon } from '@osf/shared/helpers';
import { CustomConfirmationService, LoaderService } from '@osf/shared/services';
import { Addon, AuthorizedAddon, ConfiguredAddon } from '@shared/models';
import { AddonModel, AuthorizedAddon, ConfiguredStorageAddonModel } from '@shared/models';
import { DeleteAuthorizedAddon } from '@shared/stores/addons';

@Component({
Expand All @@ -24,7 +24,7 @@ export class AddonCardComponent {
private readonly loaderService = inject(LoaderService);
private readonly actions = createDispatchMap({ deleteAuthorizedAddon: DeleteAuthorizedAddon });

readonly card = input<Addon | AuthorizedAddon | ConfiguredAddon | null>(null);
readonly card = input<AddonModel | AuthorizedAddon | ConfiguredStorageAddonModel | null>(null);
readonly cardButtonLabel = input<string>('');
readonly showDangerButton = input<boolean>(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterLink } from '@angular/router';

import { AddonFormControls, CredentialsFormat } from '@shared/enums';
import { Addon, AddonForm, AuthorizedAddon, AuthorizedAddonRequestJsonApi } from '@shared/models';
import { AddonForm, AddonModel, AuthorizedAddon, AuthorizedAddonRequestJsonApi } from '@shared/models';
import { AddonFormService } from '@shared/services/addons/addon-form.service';

@Component({
Expand All @@ -22,7 +22,7 @@ import { AddonFormService } from '@shared/services/addons/addon-form.service';
export class AddonSetupAccountFormComponent {
private addonFormService = inject(AddonFormService);

addon = input.required<Addon | AuthorizedAddon>();
addon = input.required<AddonModel | AuthorizedAddon>();
userReferenceId = input.required<string>();
addonTypeString = input.required<string>();
isSubmitting = input<boolean>(false);
Expand Down
Loading