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
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ module.exports = tseslint.config(
],
'simple-import-sort/exports': 'error',
'unused-imports/no-unused-imports': 'error',
'no-console': 'error',
},
},
{
Expand Down
6 changes: 1 addition & 5 deletions src/app/features/project/addons/addons.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { AddonsComponent } from './addons.component';

import { OSFTestingModule } from '@testing/osf.testing.module';

describe('AddonsComponent', () => {
describe('Component: Addons', () => {
let component: AddonsComponent;
let fixture: ComponentFixture<AddonsComponent>;

Expand All @@ -33,10 +33,6 @@ describe('AddonsComponent', () => {
fixture.detectChanges();
});

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

it('should render the connected description paragraph', () => {
component['selectedTab'].set(component['AddonTabValue'].ALL_ADDONS);
fixture.detectChanges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ <h2 class="align-self-center">
</div>
<osf-folder-selector
[isGoogleFilePicker]="isGoogleDrive()"
[accountId]="addon()?.baseAccountId || ''"
[accountName]="addon()?.displayName || ''"
[operationInvocationResult]="operationInvocation()?.operationResult || []"
[accountNameControl]="accountNameControl"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ <h2 class="pt-2">{{ 'settings.addons.connectAddon.chooseExistingAccount' | trans
<section class="flex flex-column gap-5">
<h2 class="pt-2">{{ 'settings.addons.connectAddon.configure' | translate }} {{ addon()?.displayName }}</h2>
<osf-folder-selector
[isGoogleFilePicker]="false"
[isGoogleFilePicker]="isGoogleDrive()"
[accountId]="chosenAccountId()"
[accountName]="chosenAccountName()"
[operationInvocationResult]="operationInvocation()?.operationResult || []"
[accountNameControl]="accountNameControl"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export class ConnectConfiguredAddonComponent {
protected chosenAccountId = signal('');
protected chosenAccountName = signal('');
protected selectedRootFolderId = signal('');
private selectedAccount = signal<AuthorizedAccountModel>({} as AuthorizedAccountModel);
public readonly isGoogleDrive = computed(() => {
return this.selectedAccount()?.externalServiceName === 'googledrive';
});

protected addonsUserReference = select(AddonsSelectors.getAddonsUserReference);
protected createdAuthorizedAddon = select(AddonsSelectors.getCreatedOrUpdatedAuthorizedAddon);
Expand Down Expand Up @@ -137,14 +141,15 @@ export class ConnectConfiguredAddonComponent {

protected handleCreateConfiguredAddon() {
const addon = this.addon();
const selectedAccount = this.currentAuthorizedAddonAccounts().find(
(account) => account.id === this.chosenAccountId()
this.selectedAccount.set(
this.currentAuthorizedAddonAccounts().find((account) => account.id === this.chosenAccountId()) ||
({} as AuthorizedAccountModel)
);
if (!addon || !selectedAccount) return;
if (!addon || !this.selectedAccount()) return;

const payload = this.addonFormService.generateConfiguredAddonCreatePayload(
addon,
selectedAccount,
this.selectedAccount(),
this.userReferenceId(),
this.resourceUri(),
this.accountNameControl.value || '',
Expand Down Expand Up @@ -181,19 +186,20 @@ export class ConnectConfiguredAddonComponent {
}

protected handleConfirmAccountConnection(): void {
const selectedAccount = this.currentAuthorizedAddonAccounts().find(
(account) => account.id === this.chosenAccountId()
this.selectedAccount.set(
this.currentAuthorizedAddonAccounts().find((account) => account.id === this.chosenAccountId()) ||
({} as AuthorizedAccountModel)
);

if (!selectedAccount) return;
if (!this.selectedAccount()) return;

const dialogRef = this.addonDialogService.openConfirmAccountConnectionDialog(selectedAccount);
const dialogRef = this.addonDialogService.openConfirmAccountConnectionDialog(this.selectedAccount());

dialogRef.subscribe((result) => {
if (result?.success) {
this.stepper()?.value.set(ProjectAddonsStepperValue.CONFIGURE_ROOT_FOLDER);
this.chosenAccountName.set(selectedAccount.displayName);
this.accountNameControl.setValue(selectedAccount.displayName);
this.chosenAccountName.set(this.selectedAccount().displayName);
this.accountNameControl.setValue(this.selectedAccount().displayName);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ <h3 class="mt-4 mb-2">
@if (isOperationInvocationSubmitting()) {
<p-skeleton width="100%" height="7.5rem" borderRadius="16" />
} @else if (isGoogleFilePicker()) {
<osf-google-file-picker [isFolderPicker]="true"></osf-google-file-picker>
<osf-google-file-picker
[isFolderPicker]="true"
[accountId]="accountId()"
[handleFolderSelection]="handleFolderSelection"
[rootFolder]="selectedRootFolder()"
></osf-google-file-picker>
} @else {
<div class="folders-table flex flex-column">
<div class="folders-table-heading flex justify-content-between">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { OperationNames } from '@osf/features/project/addons/enums';
import { FolderSelectorComponent } from '@shared/components/addons';
import { MOCK_STORE, TranslateServiceMock } from '@shared/mocks';
import { StorageItem } from '@shared/models';
import { StorageItemModel } from '@shared/models';

describe('FolderSelectorComponent', () => {
let component: FolderSelectorComponent;
Expand Down Expand Up @@ -65,11 +65,11 @@ describe('FolderSelectorComponent', () => {
});

it('should set selectedRootFolderId', () => {
const mockFolder: StorageItem = {
const mockFolder: StorageItemModel = {
itemId: 'test-folder-id',
itemName: 'Test Folder',
itemType: 'folder',
} as StorageItem;
} as StorageItemModel;

(component as any).selectedRootFolder.set(mockFolder);
(component as any).handleSave();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';

import { OperationNames } from '@osf/features/project/addons/enums';
import { OperationInvokeData, StorageItem } from '@shared/models';
import { OperationInvokeData, StorageItemModel } from '@shared/models';
import { AddonsSelectors } from '@shared/stores/addons';

import { GoogleFilePickerComponent } from './google-file-picker/google-file-picker.component';
Expand Down Expand Up @@ -56,7 +56,8 @@ export class FolderSelectorComponent implements OnInit {

isGoogleFilePicker = input.required<boolean>();
accountName = input.required<string>();
operationInvocationResult = input.required<StorageItem[]>();
accountId = input.required<string>();
operationInvocationResult = input.required<StorageItemModel[]>();
accountNameControl = input(new FormControl());
isCreateMode = input(false);

Expand All @@ -67,7 +68,7 @@ export class FolderSelectorComponent implements OnInit {
protected readonly OperationNames = OperationNames;
protected hasInputChanged = signal(false);
protected hasFolderChanged = signal(false);
protected selectedRootFolder = signal<StorageItem | null>(null);
public selectedRootFolder = signal<StorageItemModel | null>(null);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to set public if it by default public?

protected breadcrumbItems = signal<MenuItem[]>([]);
protected initiallySelectedFolder = select(AddonsSelectors.getSelectedFolder);
protected isOperationInvocationSubmitting = select(AddonsSelectors.getOperationInvocationSubmitting);
Expand Down Expand Up @@ -126,10 +127,10 @@ export class FolderSelectorComponent implements OnInit {
this.cancelSelection.emit();
}

protected handleFolderSelection(folder: StorageItem): void {
public handleFolderSelection = (folder: StorageItemModel): void => {
this.selectedRootFolder.set(folder);
this.hasFolderChanged.set(folder?.itemId !== this.initiallySelectedFolder()?.itemId);
}
};

private updateBreadcrumbs(
operationName: OperationNames,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('Component: Google File Picker', () => {
loadGapiModules: jest.fn().mockReturnValue(of(void 0)),
};

const handleFolderSelection = jest.fn();
const setDeveloperKey = jest.fn().mockReturnThis();
const setAppId = jest.fn().mockReturnThis();
const addView = jest.fn().mockReturnThis();
Expand All @@ -39,6 +40,18 @@ describe('Component: Google File Picker', () => {
selectSnapshot: jest.fn().mockReturnValue('mock-token'),
};

beforeAll(() => {
window.google = {
picker: {
Action: null,
},
};
});

afterAll(() => {
delete (window as any).google;
});

describe('isFolderPicker - true', () => {
beforeEach(async () => {
jest.clearAllMocks();
Expand Down Expand Up @@ -84,8 +97,10 @@ describe('Component: Google File Picker', () => {
fixture = TestBed.createComponent(GoogleFilePickerComponent);
component = fixture.componentInstance;
fixture.componentRef.setInput('isFolderPicker', true);
fixture.componentRef.setInput('rootFolderId', 'root-folder-id');
fixture.componentRef.setInput('selectedFolderName', 'selected-folder-name');
fixture.componentRef.setInput('rootFolder', {
itemId: 'root-folder-id',
});
fixture.componentRef.setInput('handleFolderSelection', handleFolderSelection);
fixture.componentRef.setInput('accountId', 'account-id');
fixture.detectChanges();
});
Expand Down Expand Up @@ -118,6 +133,41 @@ describe('Component: Google File Picker', () => {
expect(build).toHaveBeenCalledWith();
expect(setVisible).toHaveBeenCalledWith(true);
});

describe('pickerCallback', () => {
it('should handle a folder selection `PICKED` action', () => {
window.google.picker.Action = {
PICKED: 'PICKED',
};
component.pickerCallback(
Object({
action: 'PICKED',
docs: [
Object({
itemId: 'item id',
itemName: 'item name',
}),
],
})
);

expect(handleFolderSelection).toHaveBeenCalledWith(Object({}));
});

it('should handle a folder selection not `PICKED` action', () => {
window.google.picker.Action = {
PICKED: 'not picked',
};

component.pickerCallback(
Object({
action: 'Loading',
})
);

expect(handleFolderSelection).not.toHaveBeenCalled();
});
});
});

describe('isFolderPicker - false', () => {
Expand Down Expand Up @@ -164,8 +214,10 @@ describe('Component: Google File Picker', () => {
fixture = TestBed.createComponent(GoogleFilePickerComponent);
component = fixture.componentInstance;
fixture.componentRef.setInput('isFolderPicker', false);
fixture.componentRef.setInput('rootFolderId', 'root-folder-id');
fixture.componentRef.setInput('selectedFolderName', 'selected-folder-name');
fixture.componentRef.setInput('rootFolder', {
itemId: 'root-folder-id',
});
fixture.componentRef.setInput('handleFolderSelection', jest.fn());
fixture.detectChanges();
});

Expand Down
Loading