+ • This add-on connects your OSF project to an external service.
+ Use of this service is bound by its terms and conditions. The
+ OSF is not responsible for the service or for your use thereof.
+
+
+ • This add-on allows you to store files using an external
+ service. Files added to this add-on are not stored within the
+ OSF.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Setup new account
+
+
Account Name
+
+ This will distinguish your account from other using the same
+ addon.
+
+ Google Drive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Configure Google Drive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Configure Google Drive
+
+
+ @for (folder of folders; track folder.name) {
+
+
+
+
+ {{ folder.name }}
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/features/settings/addons/connect-addon/connect-addon.component.scss b/src/app/features/settings/addons/connect-addon/connect-addon.component.scss
new file mode 100644
index 000000000..1ace2640a
--- /dev/null
+++ b/src/app/features/settings/addons/connect-addon/connect-addon.component.scss
@@ -0,0 +1,49 @@
+@use "assets/styles/mixins" as mix;
+@use "assets/styles/variables" as var;
+
+:host {
+ flex: 1;
+ @include mix.flex-column;
+
+ .stepper-container {
+ background-color: white;
+ flex: 1;
+
+ button {
+ width: 100%;
+ }
+ }
+}
+
+.folders-list {
+ max-height: 400px;
+ overflow-y: auto;
+ padding: 1rem;
+ border: 1px solid #dee2e6;
+ border-radius: 6px;
+ background-color: #f8f9fa;
+}
+
+.folder-item {
+ padding: 0.5rem;
+ border-radius: 4px;
+
+ &:hover {
+ background-color: #e9ecef;
+ }
+
+ i {
+ color: #6c757d;
+ }
+}
+
+:host ::ng-deep {
+ .p-checkbox {
+ .p-checkbox-box {
+ &.p-highlight {
+ border-color: var(--primary-color);
+ background: var(--primary-color);
+ }
+ }
+ }
+}
diff --git a/src/app/features/settings/addons/connect-addon/connect-addon.component.spec.ts b/src/app/features/settings/addons/connect-addon/connect-addon.component.spec.ts
new file mode 100644
index 000000000..90ae04365
--- /dev/null
+++ b/src/app/features/settings/addons/connect-addon/connect-addon.component.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ConnectAddonComponent } from './connect-addon.component';
+
+describe('ConnectAddonComponent', () => {
+ let component: ConnectAddonComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ConnectAddonComponent],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(ConnectAddonComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/features/settings/addons/connect-addon/connect-addon.component.ts b/src/app/features/settings/addons/connect-addon/connect-addon.component.ts
new file mode 100644
index 000000000..e29dd6116
--- /dev/null
+++ b/src/app/features/settings/addons/connect-addon/connect-addon.component.ts
@@ -0,0 +1,96 @@
+import { Component } from '@angular/core';
+import { SubHeaderComponent } from '@shared/components/sub-header/sub-header.component';
+import { StepPanel, StepPanels, Stepper } from 'primeng/stepper';
+import { Button } from 'primeng/button';
+import { TableModule } from 'primeng/table';
+import { RouterLink } from '@angular/router';
+import { NgClass } from '@angular/common';
+import { Card } from 'primeng/card';
+import { RadioButton } from 'primeng/radiobutton';
+import { FormsModule } from '@angular/forms';
+import { Checkbox } from 'primeng/checkbox';
+
+interface Term {
+ function: string;
+ status: string;
+ type: 'warning' | 'info';
+}
+
+interface Folder {
+ name: string;
+ selected: boolean;
+}
+
+@Component({
+ selector: 'osf-connect-addon',
+ imports: [
+ SubHeaderComponent,
+ StepPanel,
+ StepPanels,
+ Stepper,
+ Button,
+ TableModule,
+ RouterLink,
+ NgClass,
+ Card,
+ FormsModule,
+ RadioButton,
+ Checkbox,
+ ],
+ templateUrl: './connect-addon.component.html',
+ styleUrl: './connect-addon.component.scss',
+ standalone: true,
+})
+export class ConnectAddonComponent {
+ radioConfig = '';
+ folders: Folder[] = [
+ { name: 'folder name example', selected: false },
+ { name: 'folder name example', selected: false },
+ { name: 'folder name example', selected: false },
+ { name: 'folder name example', selected: false },
+ { name: 'folder name example', selected: false },
+ { name: 'folder name example', selected: false },
+ ];
+ terms: Term[] = [
+ {
+ function: 'Add / Update Files',
+ status: 'You cannot add or update files for figshare within OSF.',
+ type: 'warning',
+ },
+ {
+ function: 'Delete files',
+ status: 'You cannot delete files for figshare within OSF.',
+ type: 'warning',
+ },
+ {
+ function: 'Forking',
+ status:
+ 'Only the user who first authorized the figshare add-on within source project can transfer its authorization to a forked project or component.',
+ type: 'info',
+ },
+ {
+ function: 'Logs',
+ status:
+ 'OSF tracks changes you make to your figshare content within OSF, but not changes made directly within figshare.',
+ type: 'info',
+ },
+ {
+ function: 'Permissions',
+ status:
+ 'The OSF does not change permissions for linked figshare files. Privacy changes made to an OSF project or component will not affect those set in figshare.',
+ type: 'info',
+ },
+ {
+ function: 'Registering',
+ status:
+ 'figshare content will be registered, but version history will not be copied to the registration.',
+ type: 'info',
+ },
+ {
+ function: 'View/Download File Versions',
+ status:
+ 'figshare files can be viewed/downloaded in OSF, but version history is not supported.',
+ type: 'warning',
+ },
+ ];
+}
diff --git a/src/app/features/settings/profile-settings/profile-settings.component.ts b/src/app/features/settings/profile-settings/profile-settings.component.ts
index ed4fdece4..3b11dfa1e 100644
--- a/src/app/features/settings/profile-settings/profile-settings.component.ts
+++ b/src/app/features/settings/profile-settings/profile-settings.component.ts
@@ -1,4 +1,4 @@
-import { Component } from '@angular/core';
+import { ChangeDetectionStrategy, Component } from '@angular/core';
import { SubHeaderComponent } from '@shared/components/sub-header/sub-header.component';
@Component({
@@ -6,5 +6,6 @@ import { SubHeaderComponent } from '@shared/components/sub-header/sub-header.com
imports: [SubHeaderComponent],
templateUrl: './profile-settings.component.html',
styleUrl: './profile-settings.component.scss',
+ changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ProfileSettingsComponent {}
diff --git a/src/app/features/settings/settings-container.component.scss b/src/app/features/settings/settings-container.component.scss
index 28d91b04b..ecfe63d1c 100644
--- a/src/app/features/settings/settings-container.component.scss
+++ b/src/app/features/settings/settings-container.component.scss
@@ -1,3 +1,6 @@
:host {
margin-top: 4.5rem;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
}
diff --git a/src/app/features/settings/settings.routes.ts b/src/app/features/settings/settings.routes.ts
index 6922327a2..713b9a278 100644
--- a/src/app/features/settings/settings.routes.ts
+++ b/src/app/features/settings/settings.routes.ts
@@ -27,6 +27,25 @@ export const settingsRoutes: Routes = [
(mod) => mod.DeveloperAppsComponent,
),
},
+ {
+ path: 'addons',
+ children: [
+ {
+ path: '',
+ loadComponent: () =>
+ import('./addons/addons.component').then(
+ (mod) => mod.AddonsComponent,
+ ),
+ },
+ {
+ path: 'connect-addon',
+ loadComponent: () =>
+ import('./addons/connect-addon/connect-addon.component').then(
+ (mod) => mod.ConnectAddonComponent,
+ ),
+ },
+ ],
+ },
],
},
];
diff --git a/src/app/shared/components/password-input-hint/password-input-hint.component.ts b/src/app/shared/components/password-input-hint/password-input-hint.component.ts
index 3d4310988..f35ea5d16 100644
--- a/src/app/shared/components/password-input-hint/password-input-hint.component.ts
+++ b/src/app/shared/components/password-input-hint/password-input-hint.component.ts
@@ -1,4 +1,4 @@
-import { Component, input } from '@angular/core';
+import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { BooleanOrNullOrUndefined } from '@core/helpers/types.helper';
@Component({
@@ -6,6 +6,7 @@ import { BooleanOrNullOrUndefined } from '@core/helpers/types.helper';
imports: [],
templateUrl: './password-input-hint.component.html',
styleUrl: './password-input-hint.component.scss',
+ changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PasswordInputHintComponent {
isError = input(false);
diff --git a/src/app/shared/components/search-input/search-input.component.html b/src/app/shared/components/search-input/search-input.component.html
new file mode 100644
index 000000000..d1c3a99a5
--- /dev/null
+++ b/src/app/shared/components/search-input/search-input.component.html
@@ -0,0 +1,11 @@
+