diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..3e43c5b22 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,41 @@ +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace +bun.lock + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..dba01222a --- /dev/null +++ b/.prettierrc @@ -0,0 +1,23 @@ +{ + "semi": true, + "trailingComma": "es5", + "singleQuote": true, + "printWidth": 120, + "tabWidth": 2, + "endOfLine": "auto", + "bracketSpacing": true, + "overrides": [ + { + "files": "*.scss", + "options": { + "singleQuote": false + } + }, + { + "files": "*.html", + "options": { + "printWidth": 120 + } + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 93a2be92f..739a7519a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { - "editor.formatOnSave": false, + "editor.formatOnSave": true, "eslint.format.enable": true, "editor.codeActionsOnSave": { "source.fixAll.stylelint": "explicit", @@ -9,5 +9,5 @@ "editor.defaultFormatter": "esbenp.prettier-vscode" }, "scss.lint.unknownAtRules": "ignore", - "eslint.validate": ["json"], + "eslint.validate": ["json"] } diff --git a/angular.json b/angular.json index f68268696..fb981a90c 100644 --- a/angular.json +++ b/angular.json @@ -21,9 +21,7 @@ "outputPath": "dist/osf", "index": "src/index.html", "browser": "src/main.ts", - "polyfills": [ - "zone.js" - ], + "polyfills": ["zone.js"], "tsConfig": "tsconfig.app.json", "inlineStyleLanguage": "scss", "assets": [ @@ -92,18 +90,11 @@ "test": { "builder": "@angular-devkit/build-angular:karma", "options": { - "polyfills": [ - "zone.js", - "zone.js/testing" - ], + "polyfills": ["zone.js", "zone.js/testing"], "tsConfig": "tsconfig.spec.json", "inlineStyleLanguage": "scss", - "assets": [ - "src/assets" - ], - "styles": [ - "src/assets/styles/styles.scss" - ], + "assets": ["src/assets"], + "styles": ["src/assets/styles/styles.scss"], "stylePreprocessorOptions": { "includePaths": ["src"] }, @@ -113,19 +104,14 @@ "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "src/**/*.ts", - "src/**/*.html" - ] + "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"] } } } } }, "cli": { - "schematicCollections": [ - "angular-eslint" - ], + "schematicCollections": ["angular-eslint"], "packageManager": "bun", "analytics": false } diff --git a/bun.lock b/bun.lock index 878274769..171cc5245 100644 --- a/bun.lock +++ b/bun.lock @@ -6,7 +6,6 @@ "dependencies": { "@angular/animations": "^19.2.0", "@angular/cdk": "^19.2.1", - "@angular/cli": "^19.2.0", "@angular/common": "^19.2.0", "@angular/compiler": "^19.2.0", "@angular/core": "^19.2.0", @@ -47,9 +46,9 @@ "lint-staged": "^15.4.3", "prettier": "3.5.2", "typescript": "~5.7.2", - "typescript-eslint": "8.23.0", - }, - }, + "typescript-eslint": "8.23.0" + } + } }, "packages": { "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], diff --git a/commitlint.config.cjs b/commitlint.config.cjs index 0a0e5a2a6..33a11c3e9 100644 --- a/commitlint.config.cjs +++ b/commitlint.config.cjs @@ -1,31 +1,31 @@ module.exports = { - extends: ["@commitlint/config-conventional"], + extends: ['@commitlint/config-conventional'], rules: { - "type-enum": [ + 'type-enum': [ 2, - "always", + 'always', [ - "feat", // New feature - "fix", // Bug fix - "docs", // Documentation update - "style", // Code style (formatting, missing semicolons, etc.) - "refactor", // Code refactoring (no feature changes) - "perf", // Performance improvements - "test", // Adding tests - "chore", // Build process, CI/CD, dependencies - "revert" // Reverting changes - ] + 'feat', // New feature + 'fix', // Bug fix + 'docs', // Documentation update + 'style', // Code style (formatting, missing semicolons, etc.) + 'refactor', // Code refactoring (no feature changes) + 'perf', // Performance improvements + 'test', // Adding tests + 'chore', // Build process, CI/CD, dependencies + 'revert', // Reverting changes + ], ], - "scope-empty": [2, "never"], // Scope must always be present - "subject-case": [ + 'scope-empty': [2, 'never'], // Scope must always be present + 'subject-case': [ 2, - "always", - ["sentence-case", "start-case", "lower-case"] // Enforce casing + 'always', + ['sentence-case', 'start-case', 'lower-case'], // Enforce casing ], - "subject-empty": [2, "never"], // Prevent empty subjects - "header-max-length": [2, "always", 100], // Max length of the commit message header - "body-leading-blank": [2, "always"], // Enforce blank line before the body - "footer-leading-blank": [2, "always"], // Enforce blank line before footer - "body-max-line-length": [2, "always", 200] // Set max length for body lines - } + 'subject-empty': [2, 'never'], // Prevent empty subjects + 'header-max-length': [2, 'always', 100], // Max length of the commit message header + 'body-leading-blank': [2, 'always'], // Enforce blank line before the body + 'footer-leading-blank': [2, 'always'], // Enforce blank line before footer + 'body-max-line-length': [2, 'always', 200], // Set max length for body lines + }, }; diff --git a/docs/arch.md b/docs/arch.md index 7da5851f9..c926abcef 100644 --- a/docs/arch.md +++ b/docs/arch.md @@ -56,3 +56,4 @@ ng generate component feature-name/components/new-component | ✨ **Directive** | `ng g d shared/directives/highlight` | +``` diff --git a/docs/git-convention.md b/docs/git-convention.md index 013ce2f61..9536e0628 100644 --- a/docs/git-convention.md +++ b/docs/git-convention.md @@ -22,6 +22,7 @@ short-description – a brief description of the change. # 📌 Available Types (type) ### We use the following types to categorize changes: + ```bash | Type --- Purpose | feat --- Adding a new feature @@ -40,6 +41,7 @@ short-description – a brief description of the change. # 📝 Branch Naming Examples ### Here are some examples of branch names: + ```bash * feat/1234-add-user-authentication * fix/5678-fix-login-bug @@ -48,9 +50,11 @@ short-description – a brief description of the change. * test/8765-add-e2e-tests-for-dashboard ``` + # 🛠 Example of Creating a Branch: ### To create a new branch, use the following command: + ```bash git checkout -b feat/1234-add-user-authentication @@ -58,11 +62,11 @@ git checkout -b feat/1234-add-user-authentication # 🏆 Best Practices -* ✅ Use short and clear descriptions in branch names. -* ✅ Follow a consistent style across all branches for better project structure. -* ✅ Avoid redundant words, e.g., fix/1234-fix-bug (the word "fix" is redundant). -* ✅ Use kebab-case (- instead of _ or CamelCase). -* ✅ If there is no issue ID, omit it, e.g., docs/update-contributing-guide. +- ✅ Use short and clear descriptions in branch names. +- ✅ Follow a consistent style across all branches for better project structure. +- ✅ Avoid redundant words, e.g., fix/1234-fix-bug (the word "fix" is redundant). +- ✅ Use kebab-case (- instead of \_ or CamelCase). +- ✅ If there is no issue ID, omit it, e.g., docs/update-contributing-guide. # 🔗 Additional Resources @@ -126,4 +130,3 @@ Angular Commit Guidelines: https://github.com/angular/angular/blob/main/CONTRIBU Git Flow: https://nvie.com/posts/a-successful-git-branching-model/ This branch naming and commit message strategy ensures better traceability and improves commit history readability. 🚀 - diff --git a/eslint.config.js b/eslint.config.js index 7c32eb328..df13110bc 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,90 +1,89 @@ // @ts-check -const eslint = require("@eslint/js"); -const tseslint = require("typescript-eslint"); -const angular = require("angular-eslint"); -const pluginImport = require("eslint-plugin-import"); -const pluginSimpleImportSort = require("eslint-plugin-simple-import-sort"); -const pluginUnusedImports = require("eslint-plugin-unused-imports"); +const eslint = require('@eslint/js'); +const tseslint = require('typescript-eslint'); +const angular = require('angular-eslint'); +const pluginImport = require('eslint-plugin-import'); +const pluginSimpleImportSort = require('eslint-plugin-simple-import-sort'); +const pluginUnusedImports = require('eslint-plugin-unused-imports'); +const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended'); module.exports = tseslint.config( { - files: ["**/*.ts"], + files: ['**/*.ts'], extends: [ eslint.configs.recommended, ...tseslint.configs.recommended, ...tseslint.configs.stylistic, ...angular.configs.tsRecommended, + eslintPluginPrettierRecommended, ], processor: angular.processInlineTemplates, plugins: { import: pluginImport, - "simple-import-sort": pluginSimpleImportSort, - "unused-imports": pluginUnusedImports, + 'simple-import-sort': pluginSimpleImportSort, + 'unused-imports': pluginUnusedImports, }, rules: { - "@typescript-eslint/no-unused-vars": "warn", - "@angular-eslint/directive-selector": [ - "error", + '@typescript-eslint/no-unused-vars': 'warn', + '@angular-eslint/directive-selector': [ + 'error', { - type: "attribute", - prefix: "osf", - style: "camelCase", + type: 'attribute', + prefix: 'osf', + style: 'camelCase', }, ], - "@angular-eslint/component-selector": [ - "error", + '@angular-eslint/component-selector': [ + 'error', { - type: "element", - prefix: "osf", - style: "kebab-case", + type: 'element', + prefix: 'osf', + style: 'kebab-case', }, ], - "import/first": "error", - "import/no-duplicates": "warn", - "import/newline-after-import": "warn", - "simple-import-sort/imports": [ - "warn", + 'import/first': 'error', + 'import/no-duplicates': 'warn', + 'import/newline-after-import': 'warn', + 'simple-import-sort/imports': [ + 'warn', { groups: [ // NGXS packages - ["^@ngxs"], + ['^@ngxs'], // NGX packages (ngx-... or @ngx/...) - ["^ngx-", "^@ngx"], + ['^ngx-', '^@ngx'], // Third-party packages (primeng) - ["^primeng"], + ['^primeng'], // RxJS packages (rxjs or @rxjs/...) - ["^rxjs", "^rxjs/operators"], + ['^rxjs', '^rxjs/operators'], // Angular packages - ["^@angular"], + ['^@angular'], // Internal aliases (customize as needed) - ["^@core/", "^@osf/", "^@shared/"], + ['^@core/', '^@osf/', '^@shared/'], // Side effect imports - ["^\\u0000"], + ['^\\u0000'], // Parent imports - ["^\\.\\.(?!/?$)", "^\\.\\./?$"], + ['^\\.\\.(?!/?$)', '^\\.\\./?$'], // Sibling and current directory imports - ["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"], + ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'], ], }, ], - "simple-import-sort/exports": "warn", - "unused-imports/no-unused-imports": "warn", + 'simple-import-sort/exports': 'warn', + 'unused-imports/no-unused-imports': 'warn', }, }, { - files: ["**/*.html"], - extends: [ - ...angular.configs.templateRecommended, - ...angular.configs.templateAccessibility, - ], + files: ['**/*.html'], + extends: [...angular.configs.templateRecommended, ...angular.configs.templateAccessibility], rules: {}, - }, + } ); diff --git a/package.json b/package.json index 816005c3c..b1fb161c5 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "dependencies": { "@angular/animations": "^19.2.0", "@angular/cdk": "^19.2.1", - "@angular/cli": "^19.2.0", "@angular/common": "^19.2.0", "@angular/compiler": "^19.2.0", "@angular/core": "^19.2.0", @@ -51,7 +50,9 @@ "@types/jasmine": "~5.1.0", "angular-eslint": "19.1.0", "eslint": "^9.20.0", + "eslint-config-prettier": "^10.1.5", "eslint-plugin-import": "^2.31.0", + "eslint-plugin-prettier": "^5.4.0", "eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-unused-imports": "^4.1.4", "fantasticon": "^3.0.0", diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 1f413c5e5..7ca737092 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,11 +1,6 @@ import { Store } from '@ngxs/store'; -import { - ChangeDetectionStrategy, - Component, - inject, - OnInit, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import { GetCurrentUser } from '@core/store/user'; @@ -15,7 +10,6 @@ import { GetCurrentUser } from '@core/store/user'; imports: [RouterOutlet], templateUrl: './app.component.html', styleUrl: './app.component.scss', - standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent implements OnInit { diff --git a/src/app/app.config.ts b/src/app/app.config.ts index dd7d26346..b6d04d7a1 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -7,14 +7,9 @@ import { ConfirmationService } from 'primeng/api'; import { providePrimeNG } from 'primeng/config'; import { provideHttpClient } from '@angular/common/http'; -import { - ApplicationConfig, - importProvidersFrom, - provideZoneChangeDetection, -} from '@angular/core'; +import { ApplicationConfig, importProvidersFrom, provideZoneChangeDetection } from '@angular/core'; import { provideAnimations } from '@angular/platform-browser/animations'; import { provideRouter } from '@angular/router'; -import { provideServiceWorker } from '@angular/service-worker'; import { STATES } from '@core/constants/ngxs-states.constant'; import { provideTranslation } from '@core/helpers/i18n.helper'; @@ -42,10 +37,6 @@ export const appConfig: ApplicationConfig = { }), provideAnimations(), provideHttpClient(), - provideServiceWorker('ngsw-worker.js', { - enabled: true, - registrationStrategy: 'registerWhenStable:30000', - }), ConfirmationService, importProvidersFrom(TranslateModule.forRoot(provideTranslation())), ], diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index fc1d6c8a1..6b7fd219c 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -8,10 +8,7 @@ import { ResourceFiltersState } from '@shared/components/resources/resource-filt export const routes: Routes = [ { path: '', - loadComponent: () => - import('./core/components/root/root.component').then( - (mod) => mod.RootComponent, - ), + loadComponent: () => import('./core/components/root/root.component').then((mod) => mod.RootComponent), children: [ { path: '', @@ -20,73 +17,51 @@ export const routes: Routes = [ }, { path: 'sign-up', - loadComponent: () => - import('./features/auth/sign-up/sign-up.component').then( - (mod) => mod.SignUpComponent, - ), + loadComponent: () => import('./features/auth/sign-up/sign-up.component').then((mod) => mod.SignUpComponent), }, { path: 'forgot-password', loadComponent: () => - import( - './features/auth/forgot-password/forgot-password.component' - ).then((mod) => mod.ForgotPasswordComponent), + import('./features/auth/forgot-password/forgot-password.component').then( + (mod) => mod.ForgotPasswordComponent + ), }, { path: 'reset-password', loadComponent: () => - import( - './features/auth/reset-password/reset-password.component' - ).then((mod) => mod.ResetPasswordComponent), + import('./features/auth/reset-password/reset-password.component').then((mod) => mod.ResetPasswordComponent), }, { path: 'home', - loadComponent: () => - import('./features/home/home.component').then( - (mod) => mod.HomeComponent, - ), + loadComponent: () => import('./features/home/home.component').then((mod) => mod.HomeComponent), }, { path: 'home-logged-out', loadComponent: () => - import('./features/home/logged-out/home-logged-out.component').then( - (mod) => mod.HomeLoggedOutComponent, - ), + import('./features/home/logged-out/home-logged-out.component').then((mod) => mod.HomeLoggedOutComponent), }, { path: 'support', - loadComponent: () => - import('./features/support/support.component').then( - (mod) => mod.SupportComponent, - ), + loadComponent: () => import('./features/support/support.component').then((mod) => mod.SupportComponent), }, { path: 'terms-of-use', loadComponent: () => - import('./features/terms-of-use/terms-of-use.component').then( - (mod) => mod.TermsOfUseComponent, - ), + import('./features/terms-of-use/terms-of-use.component').then((mod) => mod.TermsOfUseComponent), }, { path: 'privacy-policy', loadComponent: () => - import('./features/privacy-policy/privacy-policy.component').then( - (mod) => mod.PrivacyPolicyComponent, - ), + import('./features/privacy-policy/privacy-policy.component').then((mod) => mod.PrivacyPolicyComponent), }, { path: 'my-projects', loadComponent: () => - import('./features/my-projects/my-projects.component').then( - (mod) => mod.MyProjectsComponent, - ), + import('./features/my-projects/my-projects.component').then((mod) => mod.MyProjectsComponent), }, { path: 'my-projects/:id', - loadComponent: () => - import('@osf/features/project/project.component').then( - (mod) => mod.ProjectComponent, - ), + loadComponent: () => import('@osf/features/project/project.component').then((mod) => mod.ProjectComponent), children: [ { path: '', @@ -96,66 +71,51 @@ export const routes: Routes = [ { path: 'overview', loadComponent: () => - import( - '@osf/features/project/overview/project-overview.component' - ).then((mod) => mod.ProjectOverviewComponent), + import('@osf/features/project/overview/project-overview.component').then( + (mod) => mod.ProjectOverviewComponent + ), }, { path: 'metadata', loadComponent: () => - import( - '@osf/features/project/metadata/project-metadata.component' - ).then((mod) => mod.ProjectMetadataComponent), + import('@osf/features/project/metadata/project-metadata.component').then( + (mod) => mod.ProjectMetadataComponent + ), }, { path: 'files', loadComponent: () => - import( - '@osf/features/project/files/project-files.component' - ).then((mod) => mod.ProjectFilesComponent), + import('@osf/features/project/files/project-files.component').then((mod) => mod.ProjectFilesComponent), }, { path: 'files/:fileId', loadComponent: () => - import( - '@osf/features/project/files/file-detail/file-detail.component' - ).then((mod) => mod.FileDetailComponent), + import('@osf/features/project/files/file-detail/file-detail.component').then( + (mod) => mod.FileDetailComponent + ), }, { path: 'registrations', loadComponent: () => - import( - '@osf/features/project/registrations/registrations.component' - ).then((mod) => mod.RegistrationsComponent), + import('@osf/features/project/registrations/registrations.component').then( + (mod) => mod.RegistrationsComponent + ), }, ], }, { path: 'settings', - loadChildren: () => - import('./features/settings/settings.routes').then( - (mod) => mod.settingsRoutes, - ), + loadChildren: () => import('./features/settings/settings.routes').then((mod) => mod.settingsRoutes), }, { path: 'search', - loadComponent: () => - import('./features/search/search.component').then( - (mod) => mod.SearchComponent, - ), - providers: [ - provideStates([ResourceFiltersState, ResourceFiltersOptionsState]), - ], + loadComponent: () => import('./features/search/search.component').then((mod) => mod.SearchComponent), + providers: [provideStates([ResourceFiltersState, ResourceFiltersOptionsState])], }, { path: 'my-profile', - loadComponent: () => - import('./features/my-profile/my-profile.component').then( - (mod) => mod.MyProfileComponent, - ), - providers: [ - provideStates([ResourceFiltersState, ResourceFiltersOptionsState]), - ], + loadComponent: () => import('./features/my-profile/my-profile.component').then((mod) => mod.MyProfileComponent), + providers: [provideStates([ResourceFiltersState, ResourceFiltersOptionsState])], }, ], }, diff --git a/src/app/core/components/breadcrumb/breadcrumb.component.html b/src/app/core/components/breadcrumb/breadcrumb.component.html index 5cf0b7aca..291606465 100644 --- a/src/app/core/components/breadcrumb/breadcrumb.component.html +++ b/src/app/core/components/breadcrumb/breadcrumb.component.html @@ -1,4 +1,4 @@ -@if (parsedUrl()[0] !== "home") { +@if (parsedUrl()[0] !== 'home') { @@ -88,36 +78,27 @@

Name Example

Recent Activity

-
+
- Jeremy Wolfe removed - tag example from + Jeremy Wolfe removed tag example from Project name example
Feb 5, 2025 04:37 AM
-
+
- Jeremy Wolfe removed - tag example from + Jeremy Wolfe removed tag example from Project name example
Feb 5, 2025 04:37 AM
-
+
@@ -148,13 +129,11 @@

Contributors

Description

- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do - eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad - minim veniam, quis nostrud exercitation ullamco laboris nisi ut - aliquip ex ea commodo consequat. Duis aute irure dolor in - reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla - pariatur. Excepteur sint occaecat cupidatat non proident, sunt in - culpa qui officia deserunt mollit anim id est laborum. + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id + est laborum.
Read More @@ -165,10 +144,7 @@

Supplements

diff --git a/src/app/features/project/project.component.ts b/src/app/features/project/project.component.ts index 371f7a85a..882f9a017 100644 --- a/src/app/features/project/project.component.ts +++ b/src/app/features/project/project.component.ts @@ -1,10 +1,5 @@ import { CommonModule } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - HostBinding, - inject, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, HostBinding, inject } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { RouterOutlet } from '@angular/router'; diff --git a/src/app/features/project/registrations/registration-card/registration-card.component.html b/src/app/features/project/registrations/registration-card/registration-card.component.html index 8c4c43e12..3a37e3e94 100644 --- a/src/app/features/project/registrations/registration-card/registration-card.component.html +++ b/src/app/features/project/registrations/registration-card/registration-card.component.html @@ -3,29 +3,26 @@
- @if (registrationData()?.status === "withdrawn") { + @if (registrationData()?.status === 'withdrawn') { } - @if (registrationData()?.status === "in_progress") { + @if (registrationData()?.status === 'in_progress') { }

{{ registrationData()?.title }}

- @if (registrationData()?.status === "in_progress") { + @if (registrationData()?.status === 'in_progress') { } - @if (registrationData()?.status === "withdrawn") { + @if (registrationData()?.status === 'withdrawn') { }
-
+
Registration template: @@ -50,10 +47,7 @@

{{ registrationData()?.title }}

Contributors: - @for ( - contributor of registrationData()?.contributors; - track contributor.name - ) { + @for (contributor of registrationData()?.contributors; track contributor.name) { {{ contributor.name }} @if (!$last) { , @@ -68,17 +62,9 @@

{{ registrationData()?.title }}

- @if (registrationData()?.status === "draft") { - - + @if (registrationData()?.status === 'draft') { + + {{ registrationData()?.title }} > } @else { - @if (registrationData()?.status === "in_progress") { + @if (registrationData()?.status === 'in_progress') { } }
- @if (registrationData()?.status !== "draft") { + @if (registrationData()?.status !== 'draft') {

Open Resources

diff --git a/src/app/features/project/registrations/registration-card/registration-card.component.ts b/src/app/features/project/registrations/registration-card/registration-card.component.ts index 9cdc97def..07c9e6a15 100644 --- a/src/app/features/project/registrations/registration-card/registration-card.component.ts +++ b/src/app/features/project/registrations/registration-card/registration-card.component.ts @@ -2,12 +2,7 @@ import { Button } from 'primeng/button'; import { Card } from 'primeng/card'; import { Tag } from 'primeng/tag'; -import { - ChangeDetectionStrategy, - Component, - inject, - input, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject, input } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { IS_XSMALL } from '@shared/utils/breakpoints.tokens'; diff --git a/src/app/features/project/registrations/registrations.component.html b/src/app/features/project/registrations/registrations.component.html index 73ebf39d1..4d83ff2fc 100644 --- a/src/app/features/project/registrations/registrations.component.html +++ b/src/app/features/project/registrations/registrations.component.html @@ -1,11 +1,7 @@
- + @if (!isMobile()) { Drafts @@ -27,20 +23,14 @@ } - @for ( - registration of draftRegistrations; - track registration.registry - ) { + @for (registration of draftRegistrations; track registration.registry) { } - @for ( - registration of submittedRegistrations; - track registration.registry - ) { + @for (registration of submittedRegistrations; track registration.registry) { } diff --git a/src/app/features/project/registrations/registrations.component.ts b/src/app/features/project/registrations/registrations.component.ts index db7f05216..27fd89fb2 100644 --- a/src/app/features/project/registrations/registrations.component.ts +++ b/src/app/features/project/registrations/registrations.component.ts @@ -2,12 +2,7 @@ import { DialogService } from 'primeng/dynamicdialog'; import { Select } from 'primeng/select'; import { Tab, TabList, TabPanel, TabPanels, Tabs } from 'primeng/tabs'; -import { - ChangeDetectionStrategy, - Component, - inject, - signal, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { FormsModule } from '@angular/forms'; @@ -58,8 +53,7 @@ export class RegistrationsComponent { { name: 'Crystal Shackleford', link: '#' }, { name: 'ALLON VISHKIN', link: '#' }, ], - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt', + description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt', status: 'draft', }, { @@ -73,8 +67,7 @@ export class RegistrationsComponent { { name: 'Crystal Shackleford', link: '#' }, { name: 'ALLON VISHKIN', link: '#' }, ], - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt', + description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt', status: 'draft', }, ]; @@ -104,8 +97,7 @@ export class RegistrationsComponent { { name: 'Crystal Shackleford', link: '#' }, { name: 'Michael Pasek', link: '#' }, ], - description: - 'Lorem consectetur adipiscing elit, sed do eiusmod tempor incididunt.', + description: 'Lorem consectetur adipiscing elit, sed do eiusmod tempor incididunt.', status: 'withdrawn', }, ]; diff --git a/src/app/features/search/mappers/search.mapper.ts b/src/app/features/search/mappers/search.mapper.ts index 32bdbe033..ea7488c8e 100644 --- a/src/app/features/search/mappers/search.mapper.ts +++ b/src/app/features/search/mappers/search.mapper.ts @@ -6,22 +6,15 @@ import { ResourceType } from '@osf/features/search/models/resource-type.enum'; export function MapResources(rawItem: ResourceItem): Resource { return { id: rawItem['@id'], - resourceType: - ResourceType[ - rawItem?.resourceType[0]['@id'] as keyof typeof ResourceType - ], - dateCreated: rawItem?.dateCreated?.[0]?.['@value'] - ? new Date(rawItem?.dateCreated?.[0]?.['@value']) - : undefined, - dateModified: rawItem?.dateModified?.[0]?.['@value'] - ? new Date(rawItem?.dateModified?.[0]?.['@value']) - : undefined, + resourceType: ResourceType[rawItem?.resourceType[0]['@id'] as keyof typeof ResourceType], + dateCreated: rawItem?.dateCreated?.[0]?.['@value'] ? new Date(rawItem?.dateCreated?.[0]?.['@value']) : undefined, + dateModified: rawItem?.dateModified?.[0]?.['@value'] ? new Date(rawItem?.dateModified?.[0]?.['@value']) : undefined, creators: (rawItem?.creator ?? []).map( (creator) => ({ id: creator?.['@id'], name: creator?.name?.[0]?.['@value'], - }) as LinkItem, + }) as LinkItem ), fileName: rawItem?.fileName?.[0]?.['@value'], title: rawItem?.title?.[0]?.['@value'] ?? rawItem?.name?.[0]?.['@value'], diff --git a/src/app/features/search/models/raw-models/index-card-search.model.ts b/src/app/features/search/models/raw-models/index-card-search.model.ts index fcc18ad48..843d1bb97 100644 --- a/src/app/features/search/models/raw-models/index-card-search.model.ts +++ b/src/app/features/search/models/raw-models/index-card-search.model.ts @@ -1,7 +1,4 @@ -import { - ApiData, - JsonApiResponse, -} from '@core/services/json-api/json-api.entity'; +import { ApiData, JsonApiResponse } from '@core/services/json-api/json-api.entity'; import { ResourceItem } from '@osf/features/search/models/raw-models/resource-response.model'; export type IndexCardSearch = JsonApiResponse< diff --git a/src/app/features/search/search.component.html b/src/app/features/search/search.component.html index 5845440d6..a0a936c36 100644 --- a/src/app/features/search/search.component.html +++ b/src/app/features/search/search.component.html @@ -1,7 +1,4 @@ -
+
better-research
- + @if (!isMobile()) { All @@ -40,26 +33,13 @@ } - - - - - - - - + + + + + @if (!isMyProfilePage()) { - - + } @@ -71,17 +51,13 @@

Improved OSF Search

- Enter any term in the search box and filter by specific object types. - More information is available on our help guides. + Enter any term in the search box and filter by specific object types. More information is available on our + help guides.

1 of 3

- + Next
@@ -92,17 +68,13 @@

Improved OSF Search

Refine Your Search

- Narrow the source, discipline, and more. For example, find content - supported by a specific funder or view only datasets. + Narrow the source, discipline, and more. For example, find content supported by a specific funder or view only + datasets.

2 of 3

- + Next
@@ -113,8 +85,8 @@

Refine Your Search

Add Metadata

- Remember to add metadata and resources to your own work on OSF to make - it more discoverable! Learn more in our help guides. + Remember to add metadata and resources to your own work on OSF to make it more discoverable! Learn more in our + help guides.

3 of 3

diff --git a/src/app/features/search/search.component.ts b/src/app/features/search/search.component.ts index 92f541fb2..a92c1d75a 100644 --- a/src/app/features/search/search.component.ts +++ b/src/app/features/search/search.component.ts @@ -11,15 +11,7 @@ import { Tab, TabList, TabPanel, TabPanels, Tabs } from 'primeng/tabs'; import { debounceTime } from 'rxjs'; import { NgOptimizedImage } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - effect, - inject, - OnDestroy, - signal, - untracked, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, effect, inject, OnDestroy, signal, untracked } from '@angular/core'; import { toObservable, toSignal } from '@angular/core/rxjs-interop'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -32,10 +24,7 @@ import { SetSearchText, } from '@osf/features/search/store'; import { GetAllOptions } from '@shared/components/resources/resource-filters/filters/store/resource-filters-options.actions'; -import { - ResetFiltersState, - ResourceFiltersSelectors, -} from '@shared/components/resources/resource-filters/store'; +import { ResetFiltersState, ResourceFiltersSelectors } from '@shared/components/resources/resource-filters/store'; import { ResourcesWrapperComponent } from '@shared/components/resources/resources-wrapper/resources-wrapper.component'; import { SearchInputComponent } from '@shared/components/search-input/search-input.component'; import { IS_XSMALL } from '@shared/utils/breakpoints.tokens'; @@ -70,45 +59,19 @@ export class SearchComponent implements OnDestroy { protected searchValue = signal(''); protected readonly isMobile = toSignal(inject(IS_XSMALL)); - protected readonly creatorsFilter = this.#store.selectSignal( - ResourceFiltersSelectors.getCreator, - ); - protected readonly dateCreatedFilter = this.#store.selectSignal( - ResourceFiltersSelectors.getDateCreated, - ); - protected readonly funderFilter = this.#store.selectSignal( - ResourceFiltersSelectors.getFunder, - ); - protected readonly subjectFilter = this.#store.selectSignal( - ResourceFiltersSelectors.getSubject, - ); - protected readonly licenseFilter = this.#store.selectSignal( - ResourceFiltersSelectors.getLicense, - ); - protected readonly resourceTypeFilter = this.#store.selectSignal( - ResourceFiltersSelectors.getResourceType, - ); - protected readonly institutionFilter = this.#store.selectSignal( - ResourceFiltersSelectors.getInstitution, - ); - protected readonly providerFilter = this.#store.selectSignal( - ResourceFiltersSelectors.getProvider, - ); - protected readonly partOfCollectionFilter = this.#store.selectSignal( - ResourceFiltersSelectors.getPartOfCollection, - ); - protected searchStoreValue = this.#store.selectSignal( - SearchSelectors.getSearchText, - ); - protected resourcesTabStoreValue = this.#store.selectSignal( - SearchSelectors.getResourceTab, - ); - protected sortByStoreValue = this.#store.selectSignal( - SearchSelectors.getSortBy, - ); - readonly isMyProfilePage = this.#store.selectSignal( - SearchSelectors.getIsMyProfile, - ); + protected readonly creatorsFilter = this.#store.selectSignal(ResourceFiltersSelectors.getCreator); + protected readonly dateCreatedFilter = this.#store.selectSignal(ResourceFiltersSelectors.getDateCreated); + protected readonly funderFilter = this.#store.selectSignal(ResourceFiltersSelectors.getFunder); + protected readonly subjectFilter = this.#store.selectSignal(ResourceFiltersSelectors.getSubject); + protected readonly licenseFilter = this.#store.selectSignal(ResourceFiltersSelectors.getLicense); + protected readonly resourceTypeFilter = this.#store.selectSignal(ResourceFiltersSelectors.getResourceType); + protected readonly institutionFilter = this.#store.selectSignal(ResourceFiltersSelectors.getInstitution); + protected readonly providerFilter = this.#store.selectSignal(ResourceFiltersSelectors.getProvider); + protected readonly partOfCollectionFilter = this.#store.selectSignal(ResourceFiltersSelectors.getPartOfCollection); + protected searchStoreValue = this.#store.selectSignal(SearchSelectors.getSearchText); + protected resourcesTabStoreValue = this.#store.selectSignal(SearchSelectors.getResourceTab); + protected sortByStoreValue = this.#store.selectSignal(SearchSelectors.getSortBy); + readonly isMyProfilePage = this.#store.selectSignal(SearchSelectors.getIsMyProfile); protected selectedTab: ResourceTab = ResourceTab.All; protected readonly ResourceTab = ResourceTab; diff --git a/src/app/features/search/search.service.ts b/src/app/features/search/search.service.ts index 2104ff424..68f638ec7 100644 --- a/src/app/features/search/search.service.ts +++ b/src/app/features/search/search.service.ts @@ -19,45 +19,34 @@ export class SearchService { filters: Record, searchText: string, sortBy: string, - resourceType: string, + resourceType: string ): Observable { const params: Record = { 'cardSearchFilter[resourceType]': resourceType ?? '', 'cardSearchFilter[accessService]': 'https://staging4.osf.io/', - 'cardSearchText[*,creator.name,isContainedBy.creator.name]': - searchText ?? '', + 'cardSearchText[*,creator.name,isContainedBy.creator.name]': searchText ?? '', 'page[size]': '10', sort: sortBy, ...filters, }; - return this.#jsonApiService - .get( - `${environment.shareDomainUrl}/index-card-search`, - params, - ) - .pipe( - map((response) => { - if (response?.included) { - return { - resources: response?.included - .filter((item) => item.type === 'index-card') - .map((item) => MapResources(item.attributes.resourceMetadata)), - count: response.data.attributes.totalResultCount, - first: - response.data?.relationships?.searchResultPage?.links?.first - ?.href, - next: response.data?.relationships?.searchResultPage?.links?.next - ?.href, - previous: - response.data?.relationships?.searchResultPage?.links?.prev - ?.href, - }; - } + return this.#jsonApiService.get(`${environment.shareDomainUrl}/index-card-search`, params).pipe( + map((response) => { + if (response?.included) { + return { + resources: response?.included + .filter((item) => item.type === 'index-card') + .map((item) => MapResources(item.attributes.resourceMetadata)), + count: response.data.attributes.totalResultCount, + first: response.data?.relationships?.searchResultPage?.links?.first?.href, + next: response.data?.relationships?.searchResultPage?.links?.next?.href, + previous: response.data?.relationships?.searchResultPage?.links?.prev?.href, + }; + } - return {} as ResourcesData; - }), - ); + return {} as ResourcesData; + }) + ); } getResourcesByLink(link: string): Observable { @@ -69,18 +58,14 @@ export class SearchService { .filter((item) => item.type === 'index-card') .map((item) => MapResources(item.attributes.resourceMetadata)), count: response.data.attributes.totalResultCount, - first: - response.data?.relationships?.searchResultPage?.links?.first - ?.href, - next: response.data?.relationships?.searchResultPage?.links?.next - ?.href, - previous: - response.data?.relationships?.searchResultPage?.links?.prev?.href, + first: response.data?.relationships?.searchResultPage?.links?.first?.href, + next: response.data?.relationships?.searchResultPage?.links?.next?.href, + previous: response.data?.relationships?.searchResultPage?.links?.prev?.href, }; } return {} as ResourcesData; - }), + }) ); } } diff --git a/src/app/features/search/store/search.state.ts b/src/app/features/search/store/search.state.ts index 08086f79a..c1663c094 100644 --- a/src/app/features/search/store/search.state.ts +++ b/src/app/features/search/store/search.state.ts @@ -32,35 +32,26 @@ export class SearchState { @Action(GetResources) getResources(ctx: StateContext) { - const filters = this.store.selectSnapshot( - ResourceFiltersSelectors.getAllFilters, - ); + const filters = this.store.selectSnapshot(ResourceFiltersSelectors.getAllFilters); const filtersParams = addFiltersParams(filters); const searchText = this.store.selectSnapshot(SearchSelectors.getSearchText); const sortBy = this.store.selectSnapshot(SearchSelectors.getSortBy); - const resourceTab = this.store.selectSnapshot( - SearchSelectors.getResourceTab, - ); + const resourceTab = this.store.selectSnapshot(SearchSelectors.getResourceTab); const resourceTypes = getResourceTypes(resourceTab); - return this.searchService - .getResources(filtersParams, searchText, sortBy, resourceTypes) - .pipe( - tap((response) => { - ctx.patchState({ resources: response.resources }); - ctx.patchState({ resourcesCount: response.count }); - ctx.patchState({ first: response.first }); - ctx.patchState({ next: response.next }); - ctx.patchState({ previous: response.previous }); - }), - ); + return this.searchService.getResources(filtersParams, searchText, sortBy, resourceTypes).pipe( + tap((response) => { + ctx.patchState({ resources: response.resources }); + ctx.patchState({ resourcesCount: response.count }); + ctx.patchState({ first: response.first }); + ctx.patchState({ next: response.next }); + ctx.patchState({ previous: response.previous }); + }) + ); } @Action(GetResourcesByLink) - getResourcesByLink( - ctx: StateContext, - action: GetResourcesByLink, - ) { + getResourcesByLink(ctx: StateContext, action: GetResourcesByLink) { return this.searchService.getResourcesByLink(action.link).pipe( tap((response) => { ctx.patchState({ resources: response.resources }); @@ -68,7 +59,7 @@ export class SearchState { ctx.patchState({ first: response.first }); ctx.patchState({ next: response.next }); ctx.patchState({ previous: response.previous }); - }), + }) ); } diff --git a/src/app/features/settings/account-settings/account-settings.component.html b/src/app/features/settings/account-settings/account-settings.component.html index a07c9063d..3876b9ede 100644 --- a/src/app/features/settings/account-settings/account-settings.component.html +++ b/src/app/features/settings/account-settings/account-settings.component.html @@ -1,17 +1,12 @@ - +
@@ -99,8 +84,8 @@
@@ -167,9 +148,7 @@ aria-describedby="username-help" [formControlName]="AccountSettingsPasswordFormControls.NewPassword" /> - Enter your username to reset your password. + Enter your username to reset your password.
@@ -179,13 +158,9 @@ pInputText id="confirm-password" aria-describedby="username-help" - [formControlName]=" - AccountSettingsPasswordFormControls.ConfirmPassword - " + [formControlName]="AccountSettingsPasswordFormControls.ConfirmPassword" /> - Enter your username to reset your password. + Enter your username to reset your password.
@@ -195,8 +170,7 @@
diff --git a/src/app/features/settings/account-settings/account-settings.component.ts b/src/app/features/settings/account-settings/account-settings.component.ts index 5b53a2b00..fa895f8c6 100644 --- a/src/app/features/settings/account-settings/account-settings.component.ts +++ b/src/app/features/settings/account-settings/account-settings.component.ts @@ -21,15 +21,7 @@ import { IS_XSMALL } from '@shared/utils/breakpoints.tokens'; @Component({ selector: 'osf-account-settings', - imports: [ - Button, - Select, - RadioButton, - ReactiveFormsModule, - InputText, - Message, - SubHeaderComponent, - ], + imports: [Button, Select, RadioButton, ReactiveFormsModule, InputText, Message, SubHeaderComponent], providers: [DialogService], templateUrl: './account-settings.component.html', styleUrl: './account-settings.component.scss', @@ -50,8 +42,7 @@ export class AccountSettingsComponent { }); protected readonly optControl = new FormControl(false); protected readonly MOCK_COUNTRIES = MOCK_COUNTRIES; - protected readonly AccountSettingsPasswordFormControls = - AccountSettingsPasswordFormControls; + protected readonly AccountSettingsPasswordFormControls = AccountSettingsPasswordFormControls; private readonly dialogService = inject(DialogService); private dialogRef: DynamicDialogRef | null = null; diff --git a/src/app/features/settings/account-settings/add-email/add-email.component.html b/src/app/features/settings/account-settings/add-email/add-email.component.html index ffa64fc01..688a68d0e 100644 --- a/src/app/features/settings/account-settings/add-email/add-email.component.html +++ b/src/app/features/settings/account-settings/add-email/add-email.component.html @@ -1,32 +1,14 @@
- +
- + Cancel - - Add Email - + Add Email
diff --git a/src/app/features/settings/account-settings/add-email/add-email.component.ts b/src/app/features/settings/account-settings/add-email/add-email.component.ts index 061492f3f..4483daaf9 100644 --- a/src/app/features/settings/account-settings/add-email/add-email.component.ts +++ b/src/app/features/settings/account-settings/add-email/add-email.component.ts @@ -15,8 +15,5 @@ import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; export class AddEmailComponent { readonly dialogRef = inject(DynamicDialogRef); - protected readonly emailControl = new FormControl('', [ - Validators.email, - Validators.required, - ]); + protected readonly emailControl = new FormControl('', [Validators.email, Validators.required]); } diff --git a/src/app/features/settings/account-settings/deactivate-account/deactivate-account/deactivate-account.component.html b/src/app/features/settings/account-settings/deactivate-account/deactivate-account/deactivate-account.component.html index 0a7fc0f86..eb014acc5 100644 --- a/src/app/features/settings/account-settings/deactivate-account/deactivate-account/deactivate-account.component.html +++ b/src/app/features/settings/account-settings/deactivate-account/deactivate-account/deactivate-account.component.html @@ -2,17 +2,8 @@

Are you sure you want to to deactivate your account?

- - + - - Deactivate - + Deactivate
diff --git a/src/app/features/settings/addons/addon-card-list/addon-card-list.component.html b/src/app/features/settings/addons/addon-card-list/addon-card-list.component.html index 76c0f3ad7..80578f42a 100644 --- a/src/app/features/settings/addons/addon-card-list/addon-card-list.component.html +++ b/src/app/features/settings/addons/addon-card-list/addon-card-list.component.html @@ -2,11 +2,7 @@ @if (cards().length) { @for (card of cards(); track card.id) {
- +
} } diff --git a/src/app/features/settings/addons/addon-card-list/addon-card-list.component.ts b/src/app/features/settings/addons/addon-card-list/addon-card-list.component.ts index 710cd8786..fc59f9a11 100644 --- a/src/app/features/settings/addons/addon-card-list/addon-card-list.component.ts +++ b/src/app/features/settings/addons/addon-card-list/addon-card-list.component.ts @@ -1,10 +1,7 @@ import { Component, input } from '@angular/core'; import { AddonCardComponent } from '@osf/features/settings/addons/addon-card/addon-card.component'; -import { - Addon, - AuthorizedAddon, -} from '@osf/features/settings/addons/entities/addons.entities'; +import { Addon, AuthorizedAddon } from '@osf/features/settings/addons/entities/addons.entities'; @Component({ selector: 'osf-addon-card-list', diff --git a/src/app/features/settings/addons/addon-card/addon-card.component.html b/src/app/features/settings/addons/addon-card/addon-card.component.html index 8a19c2623..41bb42f55 100644 --- a/src/app/features/settings/addons/addon-card/addon-card.component.html +++ b/src/app/features/settings/addons/addon-card/addon-card.component.html @@ -1,22 +1,14 @@ -
+
@if (card()!.externalServiceName) { - Addon card image + Addon card image }

{{ card()?.displayName }}

-
+
@if (showDangerButton()) { {{ card()?.displayName }} } {{ card()?.displayName }}
- {{ "settings.addons.messages.deleteConfirmation.title" | translate }} + {{ 'settings.addons.messages.deleteConfirmation.title' | translate }} -

- {{ "settings.addons.messages.deleteConfirmation.message" | translate }} + {{ 'settings.addons.messages.deleteConfirmation.message' | translate }}

{ const addon = this.card(); if (addon) { - return addon.type === 'authorized-storage-accounts' - ? 'storage' - : 'citation'; + return addon.type === 'authorized-storage-accounts' ? 'storage' : 'citation'; } return ''; }); @@ -66,17 +61,15 @@ export class AddonCardComponent { const addonId = this.card()?.id; if (addonId) { this.isDisabling.set(true); - this.#store - .dispatch(new DeleteAuthorizedAddon(addonId, this.addonTypeString())) - .subscribe({ - complete: () => { - this.isDisabling.set(false); - this.isDialogVisible.set(false); - }, - error: () => { - this.isDisabling.set(false); - }, - }); + this.#store.dispatch(new DeleteAuthorizedAddon(addonId, this.addonTypeString())).subscribe({ + complete: () => { + this.isDisabling.set(false); + this.isDialogVisible.set(false); + }, + error: () => { + this.isDisabling.set(false); + }, + }); } } } diff --git a/src/app/features/settings/addons/addon.mapper.ts b/src/app/features/settings/addons/addon.mapper.ts index 8c6af83d7..6086b4d41 100644 --- a/src/app/features/settings/addons/addon.mapper.ts +++ b/src/app/features/settings/addons/addon.mapper.ts @@ -22,31 +22,26 @@ export class AddonMapper { static fromAuthorizedAddonResponse( response: AuthorizedAddonGetResponse, - included?: IncludedAddonData[], + included?: IncludedAddonData[] ): AuthorizedAddon { // Handle both storage and citation service relationships const externalServiceData = - response.relationships?.external_storage_service?.data || - response.relationships?.external_citation_service?.data; + response.relationships?.external_storage_service?.data || response.relationships?.external_citation_service?.data; const externalServiceId = externalServiceData?.id; // Find the matching service in the included data const matchingService = included?.find( (item) => - (item.type === 'external-storage-services' || - item.type === 'external-citation-services') && - item.id === externalServiceId, + (item.type === 'external-storage-services' || item.type === 'external-citation-services') && + item.id === externalServiceId )?.attributes; // Extract the relevant properties from the matching service - const externalServiceName = - (matchingService?.['external_service_name'] as string) || ''; + const externalServiceName = (matchingService?.['external_service_name'] as string) || ''; const displayName = (matchingService?.['display_name'] as string) || ''; - const credentialsFormat = - (matchingService?.['credentials_format'] as string) || ''; - const supportedFeatures = - (matchingService?.['supported_features'] as string[]) || []; + const credentialsFormat = (matchingService?.['credentials_format'] as string) || ''; + const supportedFeatures = (matchingService?.['supported_features'] as string[]) || []; return { type: response.type, diff --git a/src/app/features/settings/addons/addons.component.html b/src/app/features/settings/addons/addons.component.html index d21d40d76..8311510c6 100644 --- a/src/app/features/settings/addons/addons.component.html +++ b/src/app/features/settings/addons/addons.component.html @@ -1,17 +1,13 @@ - +
@if (!isMobile()) { - {{ "settings.addons.tabs.allAddons" | translate }} + {{ 'settings.addons.tabs.allAddons' | translate }} - {{ "settings.addons.tabs.connectedAddons" | translate }} + {{ 'settings.addons.tabs.connectedAddons' | translate }} } @@ -35,7 +31,7 @@ }

- {{ "settings.addons.description" | translate }} + {{ 'settings.addons.description' | translate }}

@@ -65,10 +61,7 @@
- +
diff --git a/src/app/features/settings/addons/addons.component.ts b/src/app/features/settings/addons/addons.component.ts index aa17680a7..4e942cd9f 100644 --- a/src/app/features/settings/addons/addons.component.ts +++ b/src/app/features/settings/addons/addons.component.ts @@ -6,14 +6,7 @@ import { AutoCompleteModule } from 'primeng/autocomplete'; import { SelectModule } from 'primeng/select'; import { Tab, TabList, TabPanel, TabPanels, Tabs } from 'primeng/tabs'; -import { - ChangeDetectionStrategy, - Component, - computed, - effect, - inject, - signal, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { FormsModule } from '@angular/forms'; @@ -58,38 +51,19 @@ export class AddonsComponent { protected readonly defaultTabValue = 0; protected readonly isMobile = toSignal(inject(IS_XSMALL)); protected readonly searchValue = signal(''); - protected readonly selectedCategory = signal( - 'external-storage-services', - ); + protected readonly selectedCategory = signal('external-storage-services'); protected readonly selectedTab = signal(this.defaultTabValue); - protected readonly currentUser = this.#store.selectSignal( - UserSelectors.getCurrentUser, - ); - protected readonly addonsUserReference = this.#store.selectSignal( - AddonsSelectors.getAddonUserReference, - ); - protected readonly storageAddons = this.#store.selectSignal( - AddonsSelectors.getStorageAddons, - ); - protected readonly citationAddons = this.#store.selectSignal( - AddonsSelectors.getCitationAddons, - ); - protected readonly authorizedStorageAddons = this.#store.selectSignal( - AddonsSelectors.getAuthorizedStorageAddons, - ); - protected readonly authorizedCitationAddons = this.#store.selectSignal( - AddonsSelectors.getAuthorizedCitationAddons, - ); + protected readonly currentUser = this.#store.selectSignal(UserSelectors.getCurrentUser); + protected readonly addonsUserReference = this.#store.selectSignal(AddonsSelectors.getAddonUserReference); + protected readonly storageAddons = this.#store.selectSignal(AddonsSelectors.getStorageAddons); + protected readonly citationAddons = this.#store.selectSignal(AddonsSelectors.getCitationAddons); + protected readonly authorizedStorageAddons = this.#store.selectSignal(AddonsSelectors.getAuthorizedStorageAddons); + protected readonly authorizedCitationAddons = this.#store.selectSignal(AddonsSelectors.getAuthorizedCitationAddons); protected readonly allAuthorizedAddons = computed(() => { - const authorizedAddons = [ - ...this.authorizedStorageAddons(), - ...this.authorizedCitationAddons(), - ]; + const authorizedAddons = [...this.authorizedStorageAddons(), ...this.authorizedCitationAddons()]; const searchValue = this.searchValue().toLowerCase(); - return authorizedAddons.filter((card) => - card.displayName.includes(searchValue), - ); + return authorizedAddons.filter((card) => card.displayName.includes(searchValue)); }); protected readonly userReferenceId = computed(() => { @@ -97,22 +71,16 @@ export class AddonsComponent { }); protected readonly currentAction = computed(() => - this.selectedCategory() === 'external-storage-services' - ? GetStorageAddons - : GetCitationAddons, + this.selectedCategory() === 'external-storage-services' ? GetStorageAddons : GetCitationAddons ); protected readonly currentAddonsState = computed(() => - this.selectedCategory() === 'external-storage-services' - ? this.storageAddons() - : this.citationAddons(), + this.selectedCategory() === 'external-storage-services' ? this.storageAddons() : this.citationAddons() ); protected readonly filteredAddonCards = computed(() => { const searchValue = this.searchValue().toLowerCase(); - return this.currentAddonsState().filter((card) => - card.externalServiceName.includes(searchValue), - ); + return this.currentAddonsState().filter((card) => card.externalServiceName.includes(searchValue)); }); protected readonly tabOptions: SelectOption[] = [ diff --git a/src/app/features/settings/addons/addons.service.ts b/src/app/features/settings/addons/addons.service.ts index ffc6b895b..6858c1109 100644 --- a/src/app/features/settings/addons/addons.service.ts +++ b/src/app/features/settings/addons/addons.service.ts @@ -31,13 +31,11 @@ export class AddonsService { getAddons(addonType: string): Observable { return this.#jsonApiService - .get< - JsonApiResponse - >(`${environment.addonsApiUrl}/external-${addonType}-services`) + .get>(`${environment.addonsApiUrl}/external-${addonType}-services`) .pipe( map((response) => { return response.data.map((item) => AddonMapper.fromResponse(item)); - }), + }) ); } @@ -51,16 +49,11 @@ export class AddonsService { }; return this.#jsonApiService - .get< - JsonApiResponse - >(environment.addonsApiUrl + '/user-references/', params) + .get>(environment.addonsApiUrl + '/user-references/', params) .pipe(map((response) => response.data)); } - getAuthorizedAddons( - addonType: string, - referenceId: string, - ): Observable { + getAuthorizedAddons(addonType: string, referenceId: string): Observable { const params = { [`fields[external-${addonType}-services]`]: 'external_service_name', }; @@ -70,37 +63,30 @@ export class AddonsService { >(`${environment.addonsApiUrl}/user-references/${referenceId}/authorized_${addonType}_accounts/?include=external-${addonType}-service`, params) .pipe( map((response) => { - return response.data.map((item) => - AddonMapper.fromAuthorizedAddonResponse(item, response.included), - ); - }), + return response.data.map((item) => AddonMapper.fromAuthorizedAddonResponse(item, response.included)); + }) ); } - createAuthorizedAddon( - addonRequestPayload: AddonRequest, - addonType: string, - ): Observable { + createAuthorizedAddon(addonRequestPayload: AddonRequest, addonType: string): Observable { return this.#jsonApiService.post( `${environment.addonsApiUrl}/authorized-${addonType}-accounts/`, - addonRequestPayload, + addonRequestPayload ); } updateAuthorizedAddon( addonRequestPayload: AddonRequest, addonType: string, - addonId: string, + addonId: string ): Observable { return this.#jsonApiService.patch( `${environment.addonsApiUrl}/authorized-${addonType}-accounts/${addonId}/`, - addonRequestPayload, + addonRequestPayload ); } deleteAuthorizedAddon(id: string, addonType: string): Observable { - return this.#jsonApiService.delete( - `${environment.addonsApiUrl}/authorized-${addonType}-accounts/${id}/`, - ); + return this.#jsonApiService.delete(`${environment.addonsApiUrl}/authorized-${addonType}-accounts/${id}/`); } } diff --git a/src/app/features/settings/addons/connect-addon/connect-addon.component.html b/src/app/features/settings/addons/connect-addon/connect-addon.component.html index 88eed5dd6..cbfdb4603 100644 --- a/src/app/features/settings/addons/connect-addon/connect-addon.component.html +++ b/src/app/features/settings/addons/connect-addon/connect-addon.component.html @@ -1,7 +1,4 @@ - +
@@ -10,21 +7,17 @@

{{ addon()?.providerName }} - {{ "settings.addons.connectAddon.terms" | translate }} + {{ 'settings.addons.connectAddon.terms' | translate }}

- {{ - "settings.addons.connectAddon.table.function" | translate - }} + {{ 'settings.addons.connectAddon.table.function' | translate }} - {{ - "settings.addons.connectAddon.table.status" | translate - }} + {{ 'settings.addons.connectAddon.table.status' | translate }} @@ -44,14 +37,10 @@

- {{ - "settings.addons.connectAddon.termsDescription" | translate - }} + {{ 'settings.addons.connectAddon.termsDescription' | translate }}

- {{ - "settings.addons.connectAddon.storageDescription" | translate - }} + {{ 'settings.addons.connectAddon.storageDescription' | translate }}

@@ -74,163 +63,109 @@

-
+

{{ isAuthorized() - ? ("settings.addons.connectAddon.reconnectAccount" - | translate) - : ("settings.addons.connectAddon.setupNewAccount" | translate) + ? ('settings.addons.connectAddon.reconnectAccount' | translate) + : ('settings.addons.connectAddon.setupNewAccount' | translate) }}

- @if ( - addon()?.credentialsFormat === - credentialsFormat.ACCESS_SECRET_KEYS - ) { + @if (addon()?.credentialsFormat === credentialsFormat.ACCESS_SECRET_KEYS) {

- {{ "settings.addons.form.fields.accessKey" | translate }} + {{ 'settings.addons.form.fields.accessKey' | translate }}

- {{ "settings.addons.form.fields.secretKey" | translate }} + {{ 'settings.addons.form.fields.secretKey' | translate }}

} - @if ( - addon()?.credentialsFormat === - credentialsFormat.DATAVERSE_API_TOKEN - ) { + @if (addon()?.credentialsFormat === credentialsFormat.DATAVERSE_API_TOKEN) {

- {{ "settings.addons.form.fields.hostUrl" | translate }} + {{ 'settings.addons.form.fields.hostUrl' | translate }}

- {{ - "settings.addons.form.fields.hostUrlDescription" | translate - }} + {{ 'settings.addons.form.fields.hostUrlDescription' | translate }}

- +

- {{ - "settings.addons.form.fields.personalAccessToken" - | translate - }} + {{ 'settings.addons.form.fields.personalAccessToken' | translate }}

} - @if ( - addon()?.credentialsFormat === - credentialsFormat.USERNAME_PASSWORD - ) { + @if (addon()?.credentialsFormat === credentialsFormat.USERNAME_PASSWORD) {

- {{ "settings.addons.form.fields.hostUrl" | translate }} + {{ 'settings.addons.form.fields.hostUrl' | translate }}

- {{ - "settings.addons.form.fields.hostUrlDescription" | translate - }} + {{ 'settings.addons.form.fields.hostUrlDescription' | translate }}

- +

- {{ "settings.addons.form.fields.username" | translate }} + {{ 'settings.addons.form.fields.username' | translate }}

- {{ "settings.addons.form.fields.password" | translate }} + {{ 'settings.addons.form.fields.password' | translate }}

- {{ - "settings.addons.form.fields.passwordDescription" - | translate - }} + {{ 'settings.addons.form.fields.passwordDescription' | translate }}

- +
} - @if ( - addon()?.credentialsFormat === credentialsFormat.REPO_TOKEN - ) { + @if (addon()?.credentialsFormat === credentialsFormat.REPO_TOKEN) {

- {{ "settings.addons.form.fields.accessKey" | translate }} + {{ 'settings.addons.form.fields.accessKey' | translate }}

- {{ "settings.addons.form.fields.secretKey" | translate }} + {{ 'settings.addons.form.fields.secretKey' | translate }}

}

- {{ "settings.addons.form.fields.accountName" | translate }} + {{ 'settings.addons.form.fields.accountName' | translate }}

- {{ - "settings.addons.form.fields.accountNameDescription" - | translate - }} + {{ 'settings.addons.form.fields.accountNameDescription' | translate }}

@@ -249,11 +184,7 @@

class="w-10rem btn-full-width" [label]="'settings.addons.form.buttons.authorize' | translate" type="submit" - [disabled]=" - !addonForm.valid || - !this.userReference().length || - isConnecting() - " + [disabled]="!addonForm.valid || !this.userReference().length || isConnecting()" > } @else { [label]="'settings.addons.form.buttons.reconnect' | translate" [link]="true" (onClick)="handleConnectStorageAddon()" - [disabled]=" - !addonForm.valid || - !this.userReference().length || - isConnecting() - " + [disabled]="!addonForm.valid || !this.userReference().length || isConnecting()" > }

@@ -286,7 +213,7 @@

- {{ "settings.addons.connectAddon.setupNewAccount" | translate }} + {{ 'settings.addons.connectAddon.setupNewAccount' | translate }}

- {{ "settings.addons.connectAddon.oauthDescription" | translate }} + {{ 'settings.addons.connectAddon.oauthDescription' | translate }}

- - {{ "settings.addons.connectAddon.startOauth" | translate }} + + {{ 'settings.addons.connectAddon.startOauth' | translate }}
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 index bced3de4a..31954e60a 100644 --- a/src/app/features/settings/addons/connect-addon/connect-addon.component.ts +++ b/src/app/features/settings/addons/connect-addon/connect-addon.component.ts @@ -10,39 +10,15 @@ import { StepPanel, StepPanels, Stepper } from 'primeng/stepper'; import { TableModule } from 'primeng/table'; import { NgClass } from '@angular/common'; -import { - Component, - computed, - effect, - inject, - signal, - viewChild, -} from '@angular/core'; -import { - FormBuilder, - FormGroup, - FormsModule, - ReactiveFormsModule, - Validators, -} from '@angular/forms'; +import { Component, computed, effect, inject, signal, viewChild } from '@angular/core'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { Router, RouterLink } from '@angular/router'; -import { - AddonForm, - AddonFormControls, -} from '@osf/features/settings/addons/entities/addon-form.entities'; +import { AddonForm, AddonFormControls } from '@osf/features/settings/addons/entities/addon-form.entities'; import { AddonTerm } from '@osf/features/settings/addons/entities/addon-terms.interface'; -import { - Addon, - AddonRequest, - AuthorizedAddon, -} from '@osf/features/settings/addons/entities/addons.entities'; +import { Addon, AddonRequest, AuthorizedAddon } from '@osf/features/settings/addons/entities/addons.entities'; import { CredentialsFormat } from '@osf/features/settings/addons/entities/credentials-format.enum'; -import { - AddonsSelectors, - CreateAuthorizedAddon, - UpdateAuthorizedAddon, -} from '@osf/features/settings/addons/store'; +import { AddonsSelectors, CreateAuthorizedAddon, UpdateAuthorizedAddon } from '@osf/features/settings/addons/store'; import { SubHeaderComponent } from '@shared/components/sub-header/sub-header.component'; import { ADDON_TERMS as addonTerms } from '../utils/addon-terms.const'; @@ -87,21 +63,14 @@ export class ConnectAddonComponent { protected readonly addon = signal(null); protected readonly addonAuthUrl = signal('/settings/addons'); protected readonly formControls = AddonFormControls; - protected readonly userReference = this.#store.selectSignal( - AddonsSelectors.getAddonUserReference, - ); - protected createdAddon = this.#store.selectSignal( - AddonsSelectors.getCreatedOrUpdatedStorageAddon, - ); + protected readonly userReference = this.#store.selectSignal(AddonsSelectors.getAddonUserReference); + protected createdAddon = this.#store.selectSignal(AddonsSelectors.getCreatedOrUpdatedStorageAddon); protected readonly isConnecting = signal(false); protected isAuthorized = computed(() => { //check if the addon is already authorized const addon = this.addon(); if (addon) { - return ( - addon.type === 'authorized-storage-accounts' || - addon.type === 'authorized-citation-accounts' - ); + return addon.type === 'authorized-storage-accounts' || addon.type === 'authorized-citation-accounts'; } return false; }); @@ -109,8 +78,7 @@ export class ConnectAddonComponent { //get the addon type string based on the addon type property const addon = this.addon(); if (addon) { - return addon.type === 'external-storage-services' || - addon.type === 'authorized-storage-accounts' + return addon.type === 'external-storage-services' || addon.type === 'authorized-storage-accounts' ? 'storage' : 'citation'; } @@ -147,11 +115,7 @@ export class ConnectAddonComponent { .dispatch( !this.isAuthorized() ? new CreateAuthorizedAddon(request, this.addonTypeString()) - : new UpdateAuthorizedAddon( - request, - this.addonTypeString(), - this.addon()!.id, - ), + : new UpdateAuthorizedAddon(request, this.addonTypeString(), this.addon()!.id) ) .subscribe({ complete: () => { @@ -174,54 +138,26 @@ export class ConnectAddonComponent { if (addon) { const formControls: Partial = { - [AddonFormControls.AccountName]: this.#fb.control( - addon.displayName || '', - Validators.required, - ), + [AddonFormControls.AccountName]: this.#fb.control(addon.displayName || '', Validators.required), }; switch (addon.credentialsFormat) { case CredentialsFormat.ACCESS_SECRET_KEYS: - formControls[AddonFormControls.AccessKey] = this.#fb.control( - '', - Validators.required, - ); - formControls[AddonFormControls.SecretKey] = this.#fb.control( - '', - Validators.required, - ); + formControls[AddonFormControls.AccessKey] = this.#fb.control('', Validators.required); + formControls[AddonFormControls.SecretKey] = this.#fb.control('', Validators.required); break; case CredentialsFormat.DATAVERSE_API_TOKEN: - formControls[AddonFormControls.HostUrl] = this.#fb.control( - '', - Validators.required, - ); - formControls[AddonFormControls.PersonalAccessToken] = - this.#fb.control('', Validators.required); + formControls[AddonFormControls.HostUrl] = this.#fb.control('', Validators.required); + formControls[AddonFormControls.PersonalAccessToken] = this.#fb.control('', Validators.required); break; case CredentialsFormat.USERNAME_PASSWORD: - formControls[AddonFormControls.HostUrl] = this.#fb.control( - '', - Validators.required, - ); - formControls[AddonFormControls.Username] = this.#fb.control( - '', - Validators.required, - ); - formControls[AddonFormControls.Password] = this.#fb.control( - '', - Validators.required, - ); + formControls[AddonFormControls.HostUrl] = this.#fb.control('', Validators.required); + formControls[AddonFormControls.Username] = this.#fb.control('', Validators.required); + formControls[AddonFormControls.Password] = this.#fb.control('', Validators.required); break; case CredentialsFormat.REPO_TOKEN: - formControls[AddonFormControls.AccessKey] = this.#fb.control( - '', - Validators.required, - ); - formControls[AddonFormControls.SecretKey] = this.#fb.control( - '', - Validators.required, - ); + formControls[AddonFormControls.AccessKey] = this.#fb.control('', Validators.required); + formControls[AddonFormControls.SecretKey] = this.#fb.control('', Validators.required); break; } return this.#fb.group(formControls as AddonForm); @@ -235,8 +171,7 @@ export class ConnectAddonComponent { const addon = this.addon()!; const credentials: Record = {}; const initiateOAuth = - addon.credentialsFormat === CredentialsFormat.OAUTH2 || - addon.credentialsFormat === CredentialsFormat.OAUTH; + addon.credentialsFormat === CredentialsFormat.OAUTH2 || addon.credentialsFormat === CredentialsFormat.OAUTH; switch (addon.credentialsFormat) { case CredentialsFormat.ACCESS_SECRET_KEYS: @@ -244,8 +179,7 @@ export class ConnectAddonComponent { credentials['secret_key'] = formValue[AddonFormControls.SecretKey]; break; case CredentialsFormat.DATAVERSE_API_TOKEN: - credentials['personal_access_token'] = - formValue[AddonFormControls.PersonalAccessToken]; + credentials['personal_access_token'] = formValue[AddonFormControls.PersonalAccessToken]; break; case CredentialsFormat.USERNAME_PASSWORD: credentials['username'] = formValue[AddonFormControls.Username]; @@ -290,18 +224,14 @@ export class ConnectAddonComponent { [`external_${this.addonTypeString()}_service`]: { data: { type: `external-${this.addonTypeString()}-services`, - id: this.isAuthorized() - ? (addon as AuthorizedAddon).externalStorageServiceId - : (addon as Addon).id, //check if addon is already authorized and set relationship ID accordingly + id: this.isAuthorized() ? (addon as AuthorizedAddon).externalStorageServiceId : (addon as Addon).id, //check if addon is already authorized and set relationship ID accordingly }, }, }; } #getTerms(): AddonTerm[] { - const addon = this.#router.getCurrentNavigation()?.extras.state?.[ - 'addon' - ] as Addon | AuthorizedAddon; + const addon = this.#router.getCurrentNavigation()?.extras.state?.['addon'] as Addon | AuthorizedAddon; if (!addon) { this.#router.navigate(['/settings/addons']); } @@ -311,16 +241,12 @@ export class ConnectAddonComponent { const provider = addon.providerName; const isCitationService = addon.type === 'external-citation-services'; - const relevantTerms = isCitationService - ? addonTerms.filter((term) => term.citation) - : addonTerms; + const relevantTerms = isCitationService ? addonTerms.filter((term) => term.citation) : addonTerms; return relevantTerms.map((term) => { const feature = term.supportedFeature; const hasFeature = supportedFeatures.includes(feature); - const hasPartialFeature = supportedFeatures.includes( - `${feature}_PARTIAL`, - ); + const hasPartialFeature = supportedFeatures.includes(`${feature}_PARTIAL`); let message: string; let type: 'warning' | 'info' | 'danger'; diff --git a/src/app/features/settings/addons/store/addons.actions.ts b/src/app/features/settings/addons/store/addons.actions.ts index 6cb8d4a41..999a18004 100644 --- a/src/app/features/settings/addons/store/addons.actions.ts +++ b/src/app/features/settings/addons/store/addons.actions.ts @@ -25,7 +25,7 @@ export class CreateAuthorizedAddon { constructor( public payload: AddonRequest, - public addonType: string, + public addonType: string ) {} } @@ -35,7 +35,7 @@ export class UpdateAuthorizedAddon { constructor( public payload: AddonRequest, public addonType: string, - public addonId: string, + public addonId: string ) {} } @@ -48,6 +48,6 @@ export class DeleteAuthorizedAddon { constructor( public payload: string, - public addonType: string, + public addonType: string ) {} } diff --git a/src/app/features/settings/addons/store/addons.state.ts b/src/app/features/settings/addons/store/addons.state.ts index 4424ba867..dec02f371 100644 --- a/src/app/features/settings/addons/store/addons.state.ts +++ b/src/app/features/settings/addons/store/addons.state.ts @@ -39,7 +39,7 @@ export class AddonsState { return this.addonsService.getAddons('storage').pipe( tap((addons) => { ctx.patchState({ storageAddons: addons }); - }), + }) ); } @@ -48,72 +48,52 @@ export class AddonsState { return this.addonsService.getAddons('citation').pipe( tap((addons) => { ctx.patchState({ citationAddons: addons }); - }), + }) ); } @Action(GetAuthorizedStorageAddons) - getAuthorizedStorageAddons( - ctx: StateContext, - action: GetAuthorizedStorageAddons, - ) { - return this.addonsService - .getAuthorizedAddons('storage', action.referenceId) - .pipe( - tap((addons) => { - ctx.patchState({ authorizedStorageAddons: addons }); - }), - ); + getAuthorizedStorageAddons(ctx: StateContext, action: GetAuthorizedStorageAddons) { + return this.addonsService.getAuthorizedAddons('storage', action.referenceId).pipe( + tap((addons) => { + ctx.patchState({ authorizedStorageAddons: addons }); + }) + ); } @Action(GetAuthorizedCitationAddons) - getAuthorizedCitationAddons( - ctx: StateContext, - action: GetAuthorizedCitationAddons, - ) { - return this.addonsService - .getAuthorizedAddons('citation', action.referenceId) - .pipe( - tap((addons) => { - ctx.patchState({ authorizedCitationAddons: addons }); - }), - ); + getAuthorizedCitationAddons(ctx: StateContext, action: GetAuthorizedCitationAddons) { + return this.addonsService.getAuthorizedAddons('citation', action.referenceId).pipe( + tap((addons) => { + ctx.patchState({ authorizedCitationAddons: addons }); + }) + ); } @Action(CreateAuthorizedAddon) - createAuthorizedAddon( - ctx: StateContext, - action: CreateAuthorizedAddon, - ): Observable { - return this.addonsService - .createAuthorizedAddon(action.payload, action.addonType) - .pipe( - tap((addon) => { - ctx.patchState({ createdUpdatedAuthorizedAddon: addon }); - const referenceId = ctx.getState().addonsUserReference[0].id; - return action.addonType === 'storage' - ? ctx.dispatch(new GetAuthorizedStorageAddons(referenceId)) - : ctx.dispatch(new GetAuthorizedCitationAddons(referenceId)); - }), - ); + createAuthorizedAddon(ctx: StateContext, action: CreateAuthorizedAddon): Observable { + return this.addonsService.createAuthorizedAddon(action.payload, action.addonType).pipe( + tap((addon) => { + ctx.patchState({ createdUpdatedAuthorizedAddon: addon }); + const referenceId = ctx.getState().addonsUserReference[0].id; + return action.addonType === 'storage' + ? ctx.dispatch(new GetAuthorizedStorageAddons(referenceId)) + : ctx.dispatch(new GetAuthorizedCitationAddons(referenceId)); + }) + ); } @Action(UpdateAuthorizedAddon) - updateAuthorizedAddon( - ctx: StateContext, - action: UpdateAuthorizedAddon, - ): Observable { - return this.addonsService - .updateAuthorizedAddon(action.payload, action.addonType, action.addonId) - .pipe( - tap((addon) => { - ctx.patchState({ createdUpdatedAuthorizedAddon: addon }); - const referenceId = ctx.getState().addonsUserReference[0].id; - return action.addonType === 'storage' - ? ctx.dispatch(new GetAuthorizedStorageAddons(referenceId)) - : ctx.dispatch(new GetAuthorizedCitationAddons(referenceId)); - }), - ); + updateAuthorizedAddon(ctx: StateContext, action: UpdateAuthorizedAddon): Observable { + return this.addonsService.updateAuthorizedAddon(action.payload, action.addonType, action.addonId).pipe( + tap((addon) => { + ctx.patchState({ createdUpdatedAuthorizedAddon: addon }); + const referenceId = ctx.getState().addonsUserReference[0].id; + return action.addonType === 'storage' + ? ctx.dispatch(new GetAuthorizedStorageAddons(referenceId)) + : ctx.dispatch(new GetAuthorizedCitationAddons(referenceId)); + }) + ); } @Action(GetAddonsUserReference) @@ -121,24 +101,19 @@ export class AddonsState { return this.addonsService.getAddonsUserReference().pipe( tap((userReference) => { ctx.patchState({ addonsUserReference: userReference }); - }), + }) ); } @Action(DeleteAuthorizedAddon) - deleteAuthorizedAddon( - ctx: StateContext, - action: DeleteAuthorizedAddon, - ) { - return this.addonsService - .deleteAuthorizedAddon(action.payload, action.addonType) - .pipe( - switchMap(() => { - const referenceId = ctx.getState().addonsUserReference[0].id; - return action.addonType === 'storage' - ? ctx.dispatch(new GetAuthorizedStorageAddons(referenceId)) - : ctx.dispatch(new GetAuthorizedCitationAddons(referenceId)); - }), - ); + deleteAuthorizedAddon(ctx: StateContext, action: DeleteAuthorizedAddon) { + return this.addonsService.deleteAuthorizedAddon(action.payload, action.addonType).pipe( + switchMap(() => { + const referenceId = ctx.getState().addonsUserReference[0].id; + return action.addonType === 'storage' + ? ctx.dispatch(new GetAuthorizedStorageAddons(referenceId)) + : ctx.dispatch(new GetAuthorizedCitationAddons(referenceId)); + }) + ); } } diff --git a/src/app/features/settings/addons/utils/addon-terms.const.ts b/src/app/features/settings/addons/utils/addon-terms.const.ts index df1b9139e..ac16a705f 100644 --- a/src/app/features/settings/addons/utils/addon-terms.const.ts +++ b/src/app/features/settings/addons/utils/addon-terms.const.ts @@ -45,8 +45,7 @@ export const ADDON_TERMS: Term[] = [ supportedFeature: 'LOGS', storage: { true: 'OSF tracks changes you make to your {provider} content within OSF, but not changes made directly within {provider}.', - false: - 'OSF does not keep track of changes made using {provider} directly.', + false: 'OSF does not keep track of changes made using {provider} directly.', }, }, { @@ -77,8 +76,7 @@ export const ADDON_TERMS: Term[] = [ supportedFeature: 'FILE_VERSIONS', storage: { true: '{provider} files and their versions can be viewed/downloaded in OSF.', - false: - '{provider} files can be viewed/downloaded in OSF, but version history is not supported.', + false: '{provider} files can be viewed/downloaded in OSF, but version history is not supported.', }, }, ]; diff --git a/src/app/features/settings/developer-apps/developer-app-add-edit-form/developer-app-add-edit-form.component.html b/src/app/features/settings/developer-apps/developer-app-add-edit-form/developer-app-add-edit-form.component.html index 01855c30c..cb939f07e 100644 --- a/src/app/features/settings/developer-apps/developer-app-add-edit-form/developer-app-add-edit-form.component.html +++ b/src/app/features/settings/developer-apps/developer-app-add-edit-form/developer-app-add-edit-form.component.html @@ -1,11 +1,7 @@ - +
- control.markAsDirty(), - ); + Object.values(this.appForm.controls).forEach((control) => control.markAsDirty()); return; } @@ -104,7 +81,7 @@ export class DeveloperAppAddEditFormComponent implements OnInit { .dispatch( new CreateDeveloperApp({ ...this.appForm.value, - } as DeveloperAppCreateUpdate), + } as DeveloperAppCreateUpdate) ) .subscribe({ complete: () => { @@ -117,7 +94,7 @@ export class DeveloperAppAddEditFormComponent implements OnInit { new UpdateDeveloperApp(this.initialValues()!.clientId, { ...this.appForm.value, id: this.initialValues()!.id, - } as DeveloperAppCreateUpdate), + } as DeveloperAppCreateUpdate) ) .subscribe({ complete: () => { diff --git a/src/app/features/settings/developer-apps/developer-app-details/developer-app-details.component.html b/src/app/features/settings/developer-apps/developer-app-details/developer-app-details.component.html index 0eea8ad77..c771b81a8 100644 --- a/src/app/features/settings/developer-apps/developer-app-details/developer-app-details.component.html +++ b/src/app/features/settings/developer-apps/developer-app-details/developer-app-details.component.html @@ -2,7 +2,7 @@ @@ -21,28 +21,20 @@

{{ developerApp()?.name }}

- {{ "settings.developerApps.details.clientId.title" | translate }} + {{ 'settings.developerApps.details.clientId.title' | translate }}

- {{ - "settings.developerApps.details.clientId.description" | translate - }} + {{ 'settings.developerApps.details.clientId.description' | translate }}

- - {{ "settings.developerApps.messages.copied" | translate }} + + {{ 'settings.developerApps.messages.copied' | translate }} - + @@ -53,36 +45,20 @@

- {{ - "settings.developerApps.details.clientSecret.title" | translate - }} + {{ 'settings.developerApps.details.clientSecret.title' | translate }}

- {{ - "settings.developerApps.details.clientSecret.description" - | translate - }} + {{ 'settings.developerApps.details.clientSecret.description' | translate }}

- - {{ "settings.developerApps.messages.copied" | translate }} + + {{ 'settings.developerApps.messages.copied' | translate }} - +
@@ -120,11 +91,8 @@

-

{{ "settings.developerApps.form.editTitle" | translate }}

- +

{{ 'settings.developerApps.form.editTitle' | translate }}

+

diff --git a/src/app/features/settings/developer-apps/developer-app-details/developer-app-details.component.ts b/src/app/features/settings/developer-apps/developer-app-details/developer-app-details.component.ts index a9c0fea9c..1185dd183 100644 --- a/src/app/features/settings/developer-apps/developer-app-details/developer-app-details.component.ts +++ b/src/app/features/settings/developer-apps/developer-app-details/developer-app-details.component.ts @@ -13,14 +13,7 @@ import { InputText } from 'primeng/inputtext'; import { map, of, switchMap, timer } from 'rxjs'; import { CdkCopyToClipboard } from '@angular/cdk/clipboard'; -import { - ChangeDetectionStrategy, - Component, - computed, - DestroyRef, - inject, - signal, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, DestroyRef, inject, signal } from '@angular/core'; import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; @@ -69,62 +62,46 @@ export class DeveloperAppDetailsComponent { this.#activatedRoute.params.pipe( map((params) => params['id']), switchMap((clientId) => { - const app = this.#store.selectSnapshot( - DeveloperAppsSelectors.getDeveloperAppDetails, - )(clientId); + const app = this.#store.selectSnapshot(DeveloperAppsSelectors.getDeveloperAppDetails)(clientId); if (!app) { this.#store.dispatch(new GetDeveloperAppDetails(clientId)); } return of(clientId); - }), - ), + }) + ) ); readonly developerApp = computed(() => { const id = this.clientId(); if (!id) return null; - const app = this.#store.selectSignal( - DeveloperAppsSelectors.getDeveloperAppDetails, - )(); + const app = this.#store.selectSignal(DeveloperAppsSelectors.getDeveloperAppDetails)(); return app(id) ?? null; }); protected readonly isClientSecretVisible = signal(false); - protected readonly clientSecret = computed( - () => this.developerApp()?.clientSecret ?? '', - ); - protected readonly hiddenClientSecret = computed(() => - '*'.repeat(this.clientSecret().length), - ); - protected readonly clientSecretCopiedNotificationVisible = - signal(false); + protected readonly clientSecret = computed(() => this.developerApp()?.clientSecret ?? ''); + protected readonly hiddenClientSecret = computed(() => '*'.repeat(this.clientSecret().length)); + protected readonly clientSecretCopiedNotificationVisible = signal(false); protected readonly clientIdCopiedNotificationVisible = signal(false); deleteApp(): void { this.#confirmationService.confirm({ ...defaultConfirmationConfig, - message: this.#translateService.instant( - 'settings.developerApps.confirmation.delete.message', - ), - header: this.#translateService.instant( - 'settings.developerApps.confirmation.delete.title', - { name: this.developerApp()?.name }, - ), + message: this.#translateService.instant('settings.developerApps.confirmation.delete.message'), + header: this.#translateService.instant('settings.developerApps.confirmation.delete.title', { + name: this.developerApp()?.name, + }), acceptButtonProps: { ...defaultConfirmationConfig.acceptButtonProps, severity: 'danger', - label: this.#translateService.instant( - 'settings.developerApps.list.deleteButton', - ), + label: this.#translateService.instant('settings.developerApps.list.deleteButton'), }, accept: () => { - this.#store - .dispatch(new DeleteDeveloperApp(this.clientId())) - .subscribe({ - complete: () => { - this.#router.navigate(['settings/developer-apps']); - }, - }); + this.#store.dispatch(new DeleteDeveloperApp(this.clientId())).subscribe({ + complete: () => { + this.#router.navigate(['settings/developer-apps']); + }, + }); }, }); } @@ -132,18 +109,12 @@ export class DeveloperAppDetailsComponent { resetClientSecret(): void { this.#confirmationService.confirm({ ...defaultConfirmationConfig, - message: this.#translateService.instant( - 'settings.developerApps.confirmation.resetSecret.message', - ), - header: this.#translateService.instant( - 'settings.developerApps.confirmation.resetSecret.title', - ), + message: this.#translateService.instant('settings.developerApps.confirmation.resetSecret.message'), + header: this.#translateService.instant('settings.developerApps.confirmation.resetSecret.title'), acceptButtonProps: { ...defaultConfirmationConfig.acceptButtonProps, severity: 'danger', - label: this.#translateService.instant( - 'settings.developerApps.details.clientSecret.reset', - ), + label: this.#translateService.instant('settings.developerApps.details.clientSecret.reset'), }, accept: () => { this.#store.dispatch(new ResetClientSecret(this.clientId())); diff --git a/src/app/features/settings/developer-apps/developer-app.mapper.ts b/src/app/features/settings/developer-apps/developer-app.mapper.ts index bdd607772..ffc8c403d 100644 --- a/src/app/features/settings/developer-apps/developer-app.mapper.ts +++ b/src/app/features/settings/developer-apps/developer-app.mapper.ts @@ -7,9 +7,7 @@ import { } from '@osf/features/settings/developer-apps/entities/developer-apps.models'; export class DeveloperAppMapper { - static toCreateRequest( - developerCreate: DeveloperAppCreateUpdate, - ): DeveloperAppCreateRequest { + static toCreateRequest(developerCreate: DeveloperAppCreateUpdate): DeveloperAppCreateRequest { return { data: { attributes: { @@ -23,9 +21,7 @@ export class DeveloperAppMapper { }; } - static toUpdateRequest( - developerUpdate: DeveloperAppCreateUpdate, - ): DeveloperAppUpdateRequest { + static toUpdateRequest(developerUpdate: DeveloperAppCreateUpdate): DeveloperAppUpdateRequest { return { data: { id: developerUpdate.id!, diff --git a/src/app/features/settings/developer-apps/developer-apps-container.component.ts b/src/app/features/settings/developer-apps/developer-apps-container.component.ts index 018b053c5..24e95f444 100644 --- a/src/app/features/settings/developer-apps/developer-apps-container.component.ts +++ b/src/app/features/settings/developer-apps/developer-apps-container.component.ts @@ -28,10 +28,8 @@ export class DeveloperAppsContainerComponent { #translateService = inject(TranslateService); protected readonly isBaseRoute = toSignal( - this.#router.events.pipe( - map(() => this.#router.url === '/settings/developer-apps'), - ), - { initialValue: this.#router.url === '/settings/developer-apps' }, + this.#router.events.pipe(map(() => this.#router.url === '/settings/developer-apps')), + { initialValue: this.#router.url === '/settings/developer-apps' } ); createDeveloperApp(): void { @@ -45,9 +43,7 @@ export class DeveloperAppsContainerComponent { this.#dialogService.open(DeveloperAppAddEditFormComponent, { width: dialogWidth, focusOnShow: false, - header: this.#translateService.instant( - 'settings.developerApps.form.createTitle', - ), + header: this.#translateService.instant('settings.developerApps.form.createTitle'), closeOnEscape: true, modal: true, closable: true, diff --git a/src/app/features/settings/developer-apps/developer-apps-list/developer-apps-list.component.html b/src/app/features/settings/developer-apps/developer-apps-list/developer-apps-list.component.html index 2cf779ada..4d43c8cd8 100644 --- a/src/app/features/settings/developer-apps/developer-apps-list/developer-apps-list.component.html +++ b/src/app/features/settings/developer-apps/developer-apps-list/developer-apps-list.component.html @@ -1,6 +1,6 @@

- {{ "settings.developerApps.list.description" | translate }} + {{ 'settings.developerApps.list.description' | translate }}

diff --git a/src/app/features/settings/developer-apps/developer-apps-list/developer-apps-list.component.ts b/src/app/features/settings/developer-apps/developer-apps-list/developer-apps-list.component.ts index bc76e9aef..551d23154 100644 --- a/src/app/features/settings/developer-apps/developer-apps-list/developer-apps-list.component.ts +++ b/src/app/features/settings/developer-apps/developer-apps-list/developer-apps-list.component.ts @@ -7,13 +7,7 @@ import { Button } from 'primeng/button'; import { Card } from 'primeng/card'; import { Skeleton } from 'primeng/skeleton'; -import { - ChangeDetectionStrategy, - Component, - inject, - OnInit, - signal, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { RouterLink } from '@angular/router'; @@ -40,26 +34,19 @@ export class DeveloperAppsListComponent implements OnInit { protected readonly isLoading = signal(false); protected readonly isXSmall = toSignal(inject(IS_XSMALL)); - readonly developerApplications = this.#store.selectSignal( - DeveloperAppsSelectors.getDeveloperApps, - ); + readonly developerApplications = this.#store.selectSignal(DeveloperAppsSelectors.getDeveloperApps); deleteApp(developerApp: DeveloperApp): void { this.#confirmationService.confirm({ ...defaultConfirmationConfig, - message: this.#translateService.instant( - 'settings.developerApps.confirmation.delete.message', - ), - header: this.#translateService.instant( - 'settings.developerApps.confirmation.delete.title', - { name: developerApp.name }, - ), + message: this.#translateService.instant('settings.developerApps.confirmation.delete.message'), + header: this.#translateService.instant('settings.developerApps.confirmation.delete.title', { + name: developerApp.name, + }), acceptButtonProps: { ...defaultConfirmationConfig.acceptButtonProps, severity: 'danger', - label: this.#translateService.instant( - 'settings.developerApps.list.deleteButton', - ), + label: this.#translateService.instant('settings.developerApps.list.deleteButton'), }, accept: () => { this.#store.dispatch(new DeleteDeveloperApp(developerApp.clientId)); diff --git a/src/app/features/settings/developer-apps/developer-apps.route.ts b/src/app/features/settings/developer-apps/developer-apps.route.ts index b3e8f176f..bfc9a358a 100644 --- a/src/app/features/settings/developer-apps/developer-apps.route.ts +++ b/src/app/features/settings/developer-apps/developer-apps.route.ts @@ -9,16 +9,12 @@ export const developerAppsRoute: Route = { { path: '', loadComponent: () => - import('./developer-apps-list/developer-apps-list.component').then( - (c) => c.DeveloperAppsListComponent, - ), + import('./developer-apps-list/developer-apps-list.component').then((c) => c.DeveloperAppsListComponent), }, { path: ':id/details', loadComponent: () => - import('./developer-app-details/developer-app-details.component').then( - (c) => c.DeveloperAppDetailsComponent, - ), + import('./developer-app-details/developer-app-details.component').then((c) => c.DeveloperAppDetailsComponent), }, ], }; diff --git a/src/app/features/settings/developer-apps/developer-apps.service.ts b/src/app/features/settings/developer-apps/developer-apps.service.ts index fc51c4589..09f4b46ad 100644 --- a/src/app/features/settings/developer-apps/developer-apps.service.ts +++ b/src/app/features/settings/developer-apps/developer-apps.service.ts @@ -19,30 +19,20 @@ export class DeveloperApplicationsService { baseUrl = 'https://api.staging4.osf.io/v2/applications/'; getApplications(): Observable { - return this.jsonApiService - .get>(this.baseUrl) - .pipe( - map((responses) => { - return responses.data.map((response) => - DeveloperAppMapper.fromGetResponse(response), - ); - }), - ); + return this.jsonApiService.get>(this.baseUrl).pipe( + map((responses) => { + return responses.data.map((response) => DeveloperAppMapper.fromGetResponse(response)); + }) + ); } getApplicationDetails(clientId: string): Observable { return this.jsonApiService - .get< - JsonApiResponse - >(this.baseUrl + clientId + '/') - .pipe( - map((response) => DeveloperAppMapper.fromGetResponse(response.data)), - ); + .get>(this.baseUrl + clientId + '/') + .pipe(map((response) => DeveloperAppMapper.fromGetResponse(response.data))); } - createApplication( - developerAppCreate: DeveloperAppCreateUpdate, - ): Observable { + createApplication(developerAppCreate: DeveloperAppCreateUpdate): Observable { const request = DeveloperAppMapper.toCreateRequest(developerAppCreate); return this.jsonApiService @@ -50,10 +40,7 @@ export class DeveloperApplicationsService { .pipe(map((response) => DeveloperAppMapper.fromGetResponse(response))); } - updateApp( - clientId: string, - developerAppUpdate: DeveloperAppCreateUpdate, - ): Observable { + updateApp(clientId: string, developerAppUpdate: DeveloperAppCreateUpdate): Observable { const request = DeveloperAppMapper.toUpdateRequest(developerAppUpdate); return this.jsonApiService diff --git a/src/app/features/settings/developer-apps/store/developer-apps.actions.ts b/src/app/features/settings/developer-apps/store/developer-apps.actions.ts index 516ec75ae..d79174736 100644 --- a/src/app/features/settings/developer-apps/store/developer-apps.actions.ts +++ b/src/app/features/settings/developer-apps/store/developer-apps.actions.ts @@ -27,7 +27,7 @@ export class UpdateDeveloperApp { constructor( public clientId: string, - public developerAppUpdate: DeveloperAppCreateUpdate, + public developerAppUpdate: DeveloperAppCreateUpdate ) {} } diff --git a/src/app/features/settings/developer-apps/store/developer-apps.selectors.ts b/src/app/features/settings/developer-apps/store/developer-apps.selectors.ts index e458a4bba..589864332 100644 --- a/src/app/features/settings/developer-apps/store/developer-apps.selectors.ts +++ b/src/app/features/settings/developer-apps/store/developer-apps.selectors.ts @@ -11,10 +11,7 @@ export class DeveloperAppsSelectors { } @Selector([DeveloperAppsState]) - static getDeveloperAppDetails( - state: DeveloperAppsStateModel, - ): (clientId: string) => DeveloperApp | undefined { - return (clientId: string) => - state.developerApps.find((app) => app.clientId === clientId); + static getDeveloperAppDetails(state: DeveloperAppsStateModel): (clientId: string) => DeveloperApp | undefined { + return (clientId: string) => state.developerApps.find((app) => app.clientId === clientId); } } diff --git a/src/app/features/settings/developer-apps/store/developer-apps.state.ts b/src/app/features/settings/developer-apps/store/developer-apps.state.ts index 33c8b6763..6638da0e0 100644 --- a/src/app/features/settings/developer-apps/store/developer-apps.state.ts +++ b/src/app/features/settings/developer-apps/store/developer-apps.state.ts @@ -1,10 +1,5 @@ import { Action, State, StateContext } from '@ngxs/store'; -import { - insertItem, - patch, - removeItem, - updateItem, -} from '@ngxs/store/operators'; +import { insertItem, patch, removeItem, updateItem } from '@ngxs/store/operators'; import { of, tap } from 'rxjs'; @@ -38,110 +33,79 @@ export class DeveloperAppsState { return this.#developerAppsService.getApplications().pipe( tap((developerApps) => { ctx.setState(patch({ developerApps })); - }), + }) ); } @Action(GetDeveloperAppDetails) - getDeveloperAppDetails( - ctx: StateContext, - action: GetDeveloperAppDetails, - ) { + getDeveloperAppDetails(ctx: StateContext, action: GetDeveloperAppDetails) { const state = ctx.getState(); - const developerAppFromState = state.developerApps.find( - (app: DeveloperApp) => app.clientId === action.clientId, - ); + const developerAppFromState = state.developerApps.find((app: DeveloperApp) => app.clientId === action.clientId); if (developerAppFromState) { return of(developerAppFromState); } - return this.#developerAppsService - .getApplicationDetails(action.clientId) - .pipe( - tap((fetchedApp) => { - ctx.setState( - patch({ - developerApps: insertItem(fetchedApp), - }), - ); - }), - ); + return this.#developerAppsService.getApplicationDetails(action.clientId).pipe( + tap((fetchedApp) => { + ctx.setState( + patch({ + developerApps: insertItem(fetchedApp), + }) + ); + }) + ); } @Action(CreateDeveloperApp) - createDeveloperApp( - ctx: StateContext, - action: CreateDeveloperApp, - ) { - return this.#developerAppsService - .createApplication(action.developerAppCreate) - .pipe( - tap((newApp) => { - ctx.setState( - patch({ - developerApps: insertItem(newApp, 0), - }), - ); - }), - ); + createDeveloperApp(ctx: StateContext, action: CreateDeveloperApp) { + return this.#developerAppsService.createApplication(action.developerAppCreate).pipe( + tap((newApp) => { + ctx.setState( + patch({ + developerApps: insertItem(newApp, 0), + }) + ); + }) + ); } @Action(UpdateDeveloperApp) - updateDeveloperApp( - ctx: StateContext, - action: UpdateDeveloperApp, - ) { - return this.#developerAppsService - .updateApp(action.clientId, action.developerAppUpdate) - .pipe( - tap((updatedApp) => { - ctx.setState( - patch({ - developerApps: updateItem( - (app) => app.clientId === action.clientId, - updatedApp, - ), - }), - ); - }), - ); + updateDeveloperApp(ctx: StateContext, action: UpdateDeveloperApp) { + return this.#developerAppsService.updateApp(action.clientId, action.developerAppUpdate).pipe( + tap((updatedApp) => { + ctx.setState( + patch({ + developerApps: updateItem((app) => app.clientId === action.clientId, updatedApp), + }) + ); + }) + ); } @Action(ResetClientSecret) - resetClientSecret( - ctx: StateContext, - action: ResetClientSecret, - ) { + resetClientSecret(ctx: StateContext, action: ResetClientSecret) { return this.#developerAppsService.resetClientSecret(action.clientId).pipe( tap((updatedApp) => { ctx.setState( patch({ - developerApps: updateItem( - (app) => app.clientId === action.clientId, - updatedApp, - ), - }), + developerApps: updateItem((app) => app.clientId === action.clientId, updatedApp), + }) ); - }), + }) ); } @Action(DeleteDeveloperApp) - deleteDeveloperApp( - ctx: StateContext, - action: DeleteDeveloperApp, - ) { + deleteDeveloperApp(ctx: StateContext, action: DeleteDeveloperApp) { return this.#developerAppsService.deleteApplication(action.clientId).pipe( tap(() => { ctx.setState( patch({ - developerApps: removeItem( - (app) => app.clientId === action.clientId, - ), - }), + developerApps: removeItem((app) => app.clientId === action.clientId), + }) ); - }), + }) ); } } diff --git a/src/app/features/settings/notifications/notifications.component.html b/src/app/features/settings/notifications/notifications.component.html index 8fc3bc434..51fd53b2e 100644 --- a/src/app/features/settings/notifications/notifications.component.html +++ b/src/app/features/settings/notifications/notifications.component.html @@ -1,12 +1,8 @@ - +
-

{{ "settings.notifications.emailPreferences.title" | translate }}

+

{{ 'settings.notifications.emailPreferences.title' | translate }}

@@ -14,17 +10,11 @@

{{ "settings.notifications.emailPreferences.title" | translate }}

- {{ - "settings.notifications.emailPreferences.items.general.description" - | translate - }} + {{ 'settings.notifications.emailPreferences.items.general.description' | translate }}
@@ -34,17 +24,11 @@

{{ "settings.notifications.emailPreferences.title" | translate }}

- {{ - "settings.notifications.emailPreferences.items.help.description" - | translate - }} + {{ 'settings.notifications.emailPreferences.items.help.description' | translate }}
@@ -52,9 +36,7 @@

{{ "settings.notifications.emailPreferences.title" | translate }}

@@ -64,51 +46,36 @@

{{ "settings.notifications.emailPreferences.title" | translate }}

- {{ "settings.notifications.notificationPreferences.title" | translate }} + {{ 'settings.notifications.notificationPreferences.title' | translate }}

- {{ "settings.notifications.notificationPreferences.note" | translate }} + {{ 'settings.notifications.notificationPreferences.note' | translate }}
- {{ - "settings.notifications.notificationPreferences.items.replies" - | translate - }} + {{ 'settings.notifications.notificationPreferences.items.replies' | translate }}
- {{ - "settings.notifications.notificationPreferences.items.comments" - | translate - }} + {{ 'settings.notifications.notificationPreferences.items.comments' | translate }}
- {{ - "settings.notifications.notificationPreferences.items.files" - | translate - }} + {{ 'settings.notifications.notificationPreferences.items.files' | translate }}
- {{ - "settings.notifications.notificationPreferences.items.mentions" - | translate - }} + {{ 'settings.notifications.notificationPreferences.items.mentions' | translate }}
- {{ - "settings.notifications.notificationPreferences.items.preprints" - | translate - }} + {{ 'settings.notifications.notificationPreferences.items.preprints' | translate }}
diff --git a/src/app/features/settings/notifications/notifications.component.ts b/src/app/features/settings/notifications/notifications.component.ts index 558558aea..833acd2c1 100644 --- a/src/app/features/settings/notifications/notifications.component.ts +++ b/src/app/features/settings/notifications/notifications.component.ts @@ -11,13 +11,7 @@ import { SubHeaderComponent } from '@shared/components/sub-header/sub-header.com @Component({ selector: 'osf-notifications', standalone: true, - imports: [ - SubHeaderComponent, - Checkbox, - Button, - DropdownModule, - TranslatePipe, - ], + imports: [SubHeaderComponent, Checkbox, Button, DropdownModule, TranslatePipe], templateUrl: './notifications.component.html', styleUrl: './notifications.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/features/settings/profile-settings/education/education.component.html b/src/app/features/settings/profile-settings/education/education.component.html index 65d515ba6..e22707278 100644 --- a/src/app/features/settings/profile-settings/education/education.component.html +++ b/src/app/features/settings/profile-settings/education/education.component.html @@ -2,26 +2,16 @@
@if (haveEducations) { - @for ( - education of educations.controls; - track education.value; - let index = $index - ) { -
+ @for (education of educations.controls; track education.value; let index = $index) { +

- {{ - "settings.profileSettings.education.title" - | translate: { index: index + 1 } - }} + {{ 'settings.profileSettings.education.title' | translate: { index: index + 1 } }}

@if (index !== 0) {
- {{ "settings.profileSettings.education.remove" | translate }} + {{ 'settings.profileSettings.education.remove' | translate }}
} @@ -30,58 +20,33 @@

- +
-
+
- +
- +
-
+
-
+
-
@@ -138,9 +96,7 @@

(click)="addEducation()" /> -
+
disabled="true" />
- +
diff --git a/src/app/features/settings/profile-settings/education/education.component.ts b/src/app/features/settings/profile-settings/education/education.component.ts index c818a4df8..b1163a077 100644 --- a/src/app/features/settings/profile-settings/education/education.component.ts +++ b/src/app/features/settings/profile-settings/education/education.component.ts @@ -7,32 +7,16 @@ import { Checkbox } from 'primeng/checkbox'; import { DatePicker } from 'primeng/datepicker'; import { InputText } from 'primeng/inputtext'; -import { - ChangeDetectionStrategy, - Component, - effect, - HostBinding, - inject, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, effect, HostBinding, inject } from '@angular/core'; import { FormArray, FormBuilder, ReactiveFormsModule } from '@angular/forms'; -import { - Education, - EducationForm, -} from '@osf/features/settings/profile-settings/education/educations.entities'; +import { Education, EducationForm } from '@osf/features/settings/profile-settings/education/educations.entities'; import { UpdateProfileSettingsEducation } from '@osf/features/settings/profile-settings/profile-settings.actions'; import { ProfileSettingsSelectors } from '@osf/features/settings/profile-settings/profile-settings.selectors'; @Component({ selector: 'osf-education', - imports: [ - ReactiveFormsModule, - Button, - InputText, - DatePicker, - Checkbox, - TranslatePipe, - ], + imports: [ReactiveFormsModule, Button, InputText, DatePicker, Checkbox, TranslatePipe], templateUrl: './education.component.html', styleUrl: './education.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -44,9 +28,7 @@ export class EducationComponent { educations: this.#fb.array([]), }); readonly #store = inject(Store); - readonly educationItems = this.#store.selectSignal( - ProfileSettingsSelectors.educations, - ); + readonly educationItems = this.#store.selectSignal(ProfileSettingsSelectors.educations); constructor() { effect(() => { @@ -58,9 +40,7 @@ export class EducationComponent { institution: [education.institution], department: [education.department], degree: [education.degree], - startDate: [ - new Date(+education.startYear, education.startMonth - 1), - ], + startDate: [new Date(+education.startYear, education.startMonth - 1)], endDate: education.ongoing ? '' : education.endYear && education.endMonth @@ -103,23 +83,17 @@ export class EducationComponent { degree: education.degree, startYear: this.setupDates(education.startDate, null).startYear, startMonth: this.setupDates(education.startDate, null).startMonth, - endYear: education.ongoing - ? null - : this.setupDates('', education.endDate).endYear, - endMonth: education.ongoing - ? null - : this.setupDates('', education.endDate).endMonth, + endYear: education.ongoing ? null : this.setupDates('', education.endDate).endYear, + endMonth: education.ongoing ? null : this.setupDates('', education.endDate).endMonth, ongoing: education.ongoing, })) satisfies Education[]; - this.#store.dispatch( - new UpdateProfileSettingsEducation({ education: formattedEducation }), - ); + this.#store.dispatch(new UpdateProfileSettingsEducation({ education: formattedEducation })); } private setupDates( startDate: Date | string, - endDate: Date | null, + endDate: Date | null ): { startYear: number; startMonth: number; diff --git a/src/app/features/settings/profile-settings/employment/employment.component.html b/src/app/features/settings/profile-settings/employment/employment.component.html index 5849eda60..befa782a3 100644 --- a/src/app/features/settings/profile-settings/employment/employment.component.html +++ b/src/app/features/settings/profile-settings/employment/employment.component.html @@ -3,26 +3,16 @@
@if (havePositions) { - @for ( - position of positions.controls; - track position.value; - let index = $index - ) { -
+ @for (position of positions.controls; track position.value; let index = $index) { +

- {{ - "settings.profileSettings.employment.title" - | translate: { index: index + 1 } - }} + {{ 'settings.profileSettings.employment.title' | translate: { index: index + 1 } }}

@if (index !== 0) {
- {{ "settings.profileSettings.employment.remove" | translate }} + {{ 'settings.profileSettings.employment.remove' | translate }}
} @@ -31,60 +21,33 @@

- +
-
+
- +
- +
-
+
-
+
-
@@ -144,9 +97,7 @@

(click)="addPosition()" /> -
+
disabled="true" />
- +
diff --git a/src/app/features/settings/profile-settings/employment/employment.component.ts b/src/app/features/settings/profile-settings/employment/employment.component.ts index 380410776..a4cc3a49f 100644 --- a/src/app/features/settings/profile-settings/employment/employment.component.ts +++ b/src/app/features/settings/profile-settings/employment/employment.component.ts @@ -7,37 +7,16 @@ import { Checkbox } from 'primeng/checkbox'; import { DatePicker } from 'primeng/datepicker'; import { InputText } from 'primeng/inputtext'; -import { - ChangeDetectionStrategy, - Component, - effect, - HostBinding, - inject, -} from '@angular/core'; -import { - FormArray, - FormBuilder, - ReactiveFormsModule, - Validators, -} from '@angular/forms'; - -import { - Employment, - EmploymentForm, -} from '@osf/features/settings/profile-settings/employment/employment.entities'; +import { ChangeDetectionStrategy, Component, effect, HostBinding, inject } from '@angular/core'; +import { FormArray, FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; + +import { Employment, EmploymentForm } from '@osf/features/settings/profile-settings/employment/employment.entities'; import { UpdateProfileSettingsEmployment } from '@osf/features/settings/profile-settings/profile-settings.actions'; import { ProfileSettingsSelectors } from '@osf/features/settings/profile-settings/profile-settings.selectors'; @Component({ selector: 'osf-employment', - imports: [ - Button, - Checkbox, - DatePicker, - InputText, - ReactiveFormsModule, - TranslatePipe, - ], + imports: [Button, Checkbox, DatePicker, InputText, ReactiveFormsModule, TranslatePipe], templateUrl: './employment.component.html', styleUrl: './employment.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -45,9 +24,7 @@ import { ProfileSettingsSelectors } from '@osf/features/settings/profile-setting export class EmploymentComponent { @HostBinding('class') classes = 'flex flex-column gap-5'; readonly #store = inject(Store); - readonly employment = this.#store.selectSignal( - ProfileSettingsSelectors.employment, - ); + readonly employment = this.#store.selectSignal(ProfileSettingsSelectors.employment); readonly #fb = inject(FormBuilder); readonly employmentForm = this.#fb.group({ positions: this.#fb.array([]), @@ -111,23 +88,17 @@ export class EmploymentComponent { institution: employment.institution, startYear: this.setupDates(employment.startDate, null).startYear, startMonth: this.setupDates(employment.startDate, null).startMonth, - endYear: employment.ongoing - ? null - : this.setupDates('', employment.endDate).endYear, - endMonth: employment.ongoing - ? null - : this.setupDates('', employment.endDate).endMonth, + endYear: employment.ongoing ? null : this.setupDates('', employment.endDate).endYear, + endMonth: employment.ongoing ? null : this.setupDates('', employment.endDate).endMonth, ongoing: !employment.ongoing, })) satisfies Employment[]; - this.#store.dispatch( - new UpdateProfileSettingsEmployment({ employment: formattedEmployments }), - ); + this.#store.dispatch(new UpdateProfileSettingsEmployment({ employment: formattedEmployments })); } private setupDates( startDate: Date | string, - endDate: Date | string | null, + endDate: Date | string | null ): { startYear: string | number; startMonth: number; diff --git a/src/app/features/settings/profile-settings/name/name.component.html b/src/app/features/settings/profile-settings/name/name.component.html index 9bb548d04..f30e09bc6 100644 --- a/src/app/features/settings/profile-settings/name/name.component.html +++ b/src/app/features/settings/profile-settings/name/name.component.html @@ -1,86 +1,52 @@

- {{ "settings.profileSettings.name.description" | translate }} + {{ 'settings.profileSettings.name.description' | translate }}

-
+
- +
- +
-
+
- +
- +
-
+
- +
- +
@@ -88,21 +54,16 @@

- {{ "settings.profileSettings.name.citationPreview.title" | translate }} + {{ 'settings.profileSettings.name.citationPreview.title' | translate }}

- {{ - "settings.profileSettings.name.citationPreview.style" | translate - }} + {{ 'settings.profileSettings.name.citationPreview.style' | translate }}

- {{ - "settings.profileSettings.name.citationPreview.citationFormat" - | translate - }} + {{ 'settings.profileSettings.name.citationPreview.citationFormat' | translate }}

@@ -114,15 +75,10 @@

Doe, J. T.

- {{ - "settings.profileSettings.name.citationPreview.style" | translate - }} + {{ 'settings.profileSettings.name.citationPreview.style' | translate }}

- {{ - "settings.profileSettings.name.citationPreview.citationFormat" - | translate - }} + {{ 'settings.profileSettings.name.citationPreview.citationFormat' | translate }}

@@ -134,9 +90,7 @@

Doe, John T.

-
+
Doe, John T.

severity="info" />
- +
diff --git a/src/app/features/settings/profile-settings/name/name.component.ts b/src/app/features/settings/profile-settings/name/name.component.ts index 1723ac6a6..382f19d7b 100644 --- a/src/app/features/settings/profile-settings/name/name.component.ts +++ b/src/app/features/settings/profile-settings/name/name.component.ts @@ -5,13 +5,7 @@ import { TranslatePipe } from '@ngx-translate/core'; import { Button } from 'primeng/button'; import { InputText } from 'primeng/inputtext'; -import { - ChangeDetectionStrategy, - Component, - effect, - HostBinding, - inject, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, effect, HostBinding, inject } from '@angular/core'; import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; import { NameForm } from '@osf/features/settings/profile-settings/name/name.entities'; @@ -53,8 +47,7 @@ export class NameComponent { } saveChanges() { - const { fullName, givenName, middleNames, familyName, suffix } = - this.form.getRawValue(); + const { fullName, givenName, middleNames, familyName, suffix } = this.form.getRawValue(); this.#store.dispatch( new UpdateProfileSettingsUser({ user: { @@ -64,7 +57,7 @@ export class NameComponent { familyName, suffix, }, - }), + }) ); } } diff --git a/src/app/features/settings/profile-settings/profile-settings.api.service.ts b/src/app/features/settings/profile-settings/profile-settings.api.service.ts index 57947e7ba..eef651d26 100644 --- a/src/app/features/settings/profile-settings/profile-settings.api.service.ts +++ b/src/app/features/settings/profile-settings/profile-settings.api.service.ts @@ -15,15 +15,10 @@ export class ProfileSettingsApiService { readonly #baseUrl = 'https://api.staging4.osf.io/v2/'; readonly #jsonApiService = inject(JsonApiService); - patchUserSettings( - userId: string, - key: keyof ProfileSettingsStateModel, - data: ProfileSettingsUpdate, - ) { + patchUserSettings(userId: string, key: keyof ProfileSettingsStateModel, data: ProfileSettingsUpdate) { const patchedData = { [key]: data }; - return this.#jsonApiService.patch>( - `${this.#baseUrl}users/${userId}/`, - { data: { type: 'users', id: userId, attributes: patchedData } }, - ); + return this.#jsonApiService.patch>(`${this.#baseUrl}users/${userId}/`, { + data: { type: 'users', id: userId, attributes: patchedData }, + }); } } diff --git a/src/app/features/settings/profile-settings/profile-settings.component.html b/src/app/features/settings/profile-settings/profile-settings.component.html index d06e33503..8da7cb27e 100644 --- a/src/app/features/settings/profile-settings/profile-settings.component.html +++ b/src/app/features/settings/profile-settings/profile-settings.component.html @@ -1,29 +1,13 @@ - +
- + @if (!isMobile()) { - {{ - "settings.profileSettings.tabs.name" | translate - }} - {{ - "settings.profileSettings.tabs.social" | translate - }} - {{ - "settings.profileSettings.tabs.employment" | translate - }} - {{ - "settings.profileSettings.tabs.education" | translate - }} + {{ 'settings.profileSettings.tabs.name' | translate }} + {{ 'settings.profileSettings.tabs.social' | translate }} + {{ 'settings.profileSettings.tabs.employment' | translate }} + {{ 'settings.profileSettings.tabs.education' | translate }} } diff --git a/src/app/features/settings/profile-settings/profile-settings.entities.ts b/src/app/features/settings/profile-settings/profile-settings.entities.ts index f20b16ff3..b24371ec5 100644 --- a/src/app/features/settings/profile-settings/profile-settings.entities.ts +++ b/src/app/features/settings/profile-settings/profile-settings.entities.ts @@ -12,11 +12,7 @@ export interface ProfileSettingsStateModel { user: Partial; } -export type ProfileSettingsUpdate = - | Partial[] - | Partial[] - | Partial - | Partial; +export type ProfileSettingsUpdate = Partial[] | Partial[] | Partial | Partial; export const PROFILE_SETTINGS_INITIAL_STATE: ProfileSettingsStateModel = { employment: [], diff --git a/src/app/features/settings/profile-settings/profile-settings.state.ts b/src/app/features/settings/profile-settings/profile-settings.state.ts index f68e70ef9..dce8fabfa 100644 --- a/src/app/features/settings/profile-settings/profile-settings.state.ts +++ b/src/app/features/settings/profile-settings/profile-settings.state.ts @@ -34,9 +34,7 @@ export class ProfileSettingsState { @Action(SetupProfileSettings) setupProfileSettings(ctx: StateContext): void { const state = ctx.getState(); - const profileSettings = this.#store.selectSnapshot( - UserSelectors.getProfileSettings, - ); + const profileSettings = this.#store.selectSnapshot(UserSelectors.getProfileSettings); ctx.patchState({ ...state, @@ -47,7 +45,7 @@ export class ProfileSettingsState { @Action(UpdateProfileSettingsEmployment) updateProfileSettingsEmployment( ctx: StateContext, - { payload }: UpdateProfileSettingsEmployment, + { payload }: UpdateProfileSettingsEmployment ) { const state = ctx.getState(); const userId = state.user.id; @@ -60,22 +58,20 @@ export class ProfileSettingsState { return removeNullable(item); }); - return this.#profileSettingsService - .patchUserSettings(userId, 'employment', withoutNulls) - .pipe( - tap((response) => { - ctx.patchState({ - ...state, - employment: response.data.attributes.employment, - }); - }), - ); + return this.#profileSettingsService.patchUserSettings(userId, 'employment', withoutNulls).pipe( + tap((response) => { + ctx.patchState({ + ...state, + employment: response.data.attributes.employment, + }); + }) + ); } @Action(UpdateProfileSettingsEducation) updateProfileSettingsEducation( ctx: StateContext, - { payload }: UpdateProfileSettingsEducation, + { payload }: UpdateProfileSettingsEducation ) { const state = ctx.getState(); const userId = state.user.id; @@ -88,23 +84,18 @@ export class ProfileSettingsState { return removeNullable(item); }); - return this.#profileSettingsService - .patchUserSettings(userId, 'education', withoutNulls) - .pipe( - tap((response) => { - ctx.patchState({ - ...state, - education: response.data.attributes.education, - }); - }), - ); + return this.#profileSettingsService.patchUserSettings(userId, 'education', withoutNulls).pipe( + tap((response) => { + ctx.patchState({ + ...state, + education: response.data.attributes.education, + }); + }) + ); } @Action(UpdateProfileSettingsUser) - updateProfileSettingsUser( - ctx: StateContext, - { payload }: UpdateProfileSettingsUser, - ) { + updateProfileSettingsUser(ctx: StateContext, { payload }: UpdateProfileSettingsUser) { const state = ctx.getState(); const userId = state.user.id; @@ -114,22 +105,20 @@ export class ProfileSettingsState { const withoutNulls = mapNameToDto(removeNullable(payload.user)); - return this.#profileSettingsService - .patchUserSettings(userId, 'user', withoutNulls) - .pipe( - tap((response) => { - ctx.patchState({ - ...state, - user: response.data.attributes, - }); - }), - ); + return this.#profileSettingsService.patchUserSettings(userId, 'user', withoutNulls).pipe( + tap((response) => { + ctx.patchState({ + ...state, + user: response.data.attributes, + }); + }) + ); } @Action(UpdateProfileSettingsSocialLinks) updateProfileSettingsSocialLinks( ctx: StateContext, - { payload }: UpdateProfileSettingsSocialLinks, + { payload }: UpdateProfileSettingsSocialLinks ) { const state = ctx.getState(); const userId = state.user.id; @@ -147,15 +136,13 @@ export class ProfileSettingsState { }; }); - return this.#profileSettingsService - .patchUserSettings(userId, 'social', social) - .pipe( - tap((response) => { - ctx.patchState({ - ...state, - social: response.data.attributes.social, - }); - }), - ); + return this.#profileSettingsService.patchUserSettings(userId, 'social', social).pipe( + tap((response) => { + ctx.patchState({ + ...state, + social: response.data.attributes.social, + }); + }) + ); } } diff --git a/src/app/features/settings/profile-settings/social/social.component.html b/src/app/features/settings/profile-settings/social/social.component.html index 13dde1c38..11f5d1d82 100644 --- a/src/app/features/settings/profile-settings/social/social.component.html +++ b/src/app/features/settings/profile-settings/social/social.component.html @@ -8,26 +8,21 @@ >

- {{ - "settings.profileSettings.social.title" - | translate: { index: index + 1 } - }} + {{ 'settings.profileSettings.social.title' | translate: { index: index + 1 } }}

@if (index !== 0) {
- {{ "settings.profileSettings.social.remove" | translate }} + {{ 'settings.profileSettings.social.remove' | translate }}
}
-
+

- {{ "settings.profileSettings.social.socialOutput" | translate }} + {{ 'settings.profileSettings.social.socialOutput' | translate }}

- {{ "settings.profileSettings.social.webAddress" | translate }} + {{ 'settings.profileSettings.social.webAddress' | translate }}

{{ getDomain(index) }} - +
@@ -64,9 +55,7 @@

(click)="addLink()" /> -
+
disabled="true" />
- +
diff --git a/src/app/features/settings/profile-settings/social/social.component.ts b/src/app/features/settings/profile-settings/social/social.component.ts index 04c9889df..cfcc2bd14 100644 --- a/src/app/features/settings/profile-settings/social/social.component.ts +++ b/src/app/features/settings/profile-settings/social/social.component.ts @@ -8,19 +8,8 @@ import { InputGroup } from 'primeng/inputgroup'; import { InputGroupAddon } from 'primeng/inputgroupaddon'; import { InputText } from 'primeng/inputtext'; -import { - ChangeDetectionStrategy, - Component, - effect, - HostBinding, - inject, -} from '@angular/core'; -import { - FormArray, - FormBuilder, - ReactiveFormsModule, - Validators, -} from '@angular/forms'; +import { ChangeDetectionStrategy, Component, effect, HostBinding, inject } from '@angular/core'; +import { FormArray, FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; import { socials } from '@osf/features/settings/profile-settings/data'; import { UserSocialLink } from '@osf/features/settings/profile-settings/entities/user-social-link.entity'; @@ -35,15 +24,7 @@ import { @Component({ selector: 'osf-social', - imports: [ - Button, - DropdownModule, - InputGroup, - InputGroupAddon, - InputText, - ReactiveFormsModule, - TranslatePipe, - ], + imports: [Button, DropdownModule, InputGroup, InputGroupAddon, InputText, ReactiveFormsModule, TranslatePipe], templateUrl: './social.component.html', styleUrl: './social.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -53,9 +34,7 @@ export class SocialComponent { readonly userSocialLinks: UserSocialLink[] = []; protected readonly socials = socials; readonly #store = inject(Store); - readonly socialLinks = this.#store.selectSignal( - ProfileSettingsSelectors.socialLinks, - ); + readonly socialLinks = this.#store.selectSignal(ProfileSettingsSelectors.socialLinks); readonly #fb = inject(FormBuilder); readonly socialLinksForm = this.#fb.group({ links: this.#fb.array([]), @@ -71,10 +50,7 @@ export class SocialComponent { console.log(socialLink); const socialLinkGroup = this.#fb.group({ - socialOutput: [ - this.socials.find((social) => social.key === socialLinksKey), - Validators.required, - ], + socialOutput: [this.socials.find((social) => social.key === socialLinksKey), Validators.required], webAddress: [socialLink, Validators.required], }); @@ -114,17 +90,13 @@ export class SocialComponent { const mappedLinks = links.map((link) => { const key = link.socialOutput.key as SocialLinksKeys; - const value = SOCIAL_KEYS.includes(key) - ? [link.webAddress] - : link.webAddress; + const value = SOCIAL_KEYS.includes(key) ? [link.webAddress] : link.webAddress; return { [key]: value, }; }) satisfies Partial[]; - this.#store.dispatch( - new UpdateProfileSettingsSocialLinks({ socialLinks: mappedLinks }), - ); + this.#store.dispatch(new UpdateProfileSettingsSocialLinks({ socialLinks: mappedLinks })); } } diff --git a/src/app/features/settings/profile-settings/social/social.entities.ts b/src/app/features/settings/profile-settings/social/social.entities.ts index ce9cc5739..8ddae61d2 100644 --- a/src/app/features/settings/profile-settings/social/social.entities.ts +++ b/src/app/features/settings/profile-settings/social/social.entities.ts @@ -16,12 +16,7 @@ export interface Social { export type SocialLinksKeys = keyof Social; -export const SOCIAL_KEYS: SocialLinksKeys[] = [ - 'github', - 'twitter', - 'linkedIn', - 'profileWebsites', -]; +export const SOCIAL_KEYS: SocialLinksKeys[] = ['github', 'twitter', 'linkedIn', 'profileWebsites']; export interface SocialLinksEntity { id: number; diff --git a/src/app/features/settings/settings.routes.ts b/src/app/features/settings/settings.routes.ts index cc01e4ac0..b2394e10c 100644 --- a/src/app/features/settings/settings.routes.ts +++ b/src/app/features/settings/settings.routes.ts @@ -12,16 +12,12 @@ export const settingsRoutes: Routes = [ { path: 'profile-settings', loadComponent: () => - import('./profile-settings/profile-settings.component').then( - (c) => c.ProfileSettingsComponent, - ), + import('./profile-settings/profile-settings.component').then((c) => c.ProfileSettingsComponent), }, { path: 'account-settings', loadComponent: () => - import('./account-settings/account-settings.component').then( - (c) => c.AccountSettingsComponent, - ), + import('./account-settings/account-settings.component').then((c) => c.AccountSettingsComponent), }, developerAppsRoute, { @@ -29,17 +25,12 @@ export const settingsRoutes: Routes = [ children: [ { path: '', - loadComponent: () => - import('./addons/addons.component').then( - (mod) => mod.AddonsComponent, - ), + loadComponent: () => import('./addons/addons.component').then((mod) => mod.AddonsComponent), }, { path: 'connect-addon', loadComponent: () => - import('./addons/connect-addon/connect-addon.component').then( - (mod) => mod.ConnectAddonComponent, - ), + import('./addons/connect-addon/connect-addon.component').then((mod) => mod.ConnectAddonComponent), }, ], }, @@ -47,9 +38,7 @@ export const settingsRoutes: Routes = [ { path: 'notifications', loadComponent: () => - import('./notifications/notifications.component').then( - (mod) => mod.NotificationsComponent, - ), + import('./notifications/notifications.component').then((mod) => mod.NotificationsComponent), }, ], }, diff --git a/src/app/features/settings/tokens/store/tokens.actions.ts b/src/app/features/settings/tokens/store/tokens.actions.ts index 54a657610..a71e493af 100644 --- a/src/app/features/settings/tokens/store/tokens.actions.ts +++ b/src/app/features/settings/tokens/store/tokens.actions.ts @@ -16,7 +16,7 @@ export class UpdateToken { constructor( public tokenId: string, public name: string, - public scopes: string[], + public scopes: string[] ) {} } @@ -29,6 +29,6 @@ export class CreateToken { static readonly type = '[Tokens] Create Token'; constructor( public name: string, - public scopes: string[], + public scopes: string[] ) {} } diff --git a/src/app/features/settings/tokens/store/tokens.selectors.ts b/src/app/features/settings/tokens/store/tokens.selectors.ts index 1f4c08167..57075af2b 100644 --- a/src/app/features/settings/tokens/store/tokens.selectors.ts +++ b/src/app/features/settings/tokens/store/tokens.selectors.ts @@ -18,9 +18,7 @@ export class TokensSelectors { } @Selector([TokensState]) - static getTokenById( - state: TokensStateModel, - ): (id: string) => Token | undefined { + static getTokenById(state: TokensStateModel): (id: string) => Token | undefined { return (id: string) => state.tokens.find((token) => token.id === id); } } diff --git a/src/app/features/settings/tokens/store/tokens.state.ts b/src/app/features/settings/tokens/store/tokens.state.ts index 140ce00ac..c33f600ca 100644 --- a/src/app/features/settings/tokens/store/tokens.state.ts +++ b/src/app/features/settings/tokens/store/tokens.state.ts @@ -7,14 +7,7 @@ import { inject, Injectable } from '@angular/core'; import { Token } from '@osf/features/settings/tokens/entities/tokens.models'; import { TokensService } from '@osf/features/settings/tokens/tokens.service'; -import { - CreateToken, - DeleteToken, - GetScopes, - GetTokenById, - GetTokens, - UpdateToken, -} from './tokens.actions'; +import { CreateToken, DeleteToken, GetScopes, GetTokenById, GetTokens, UpdateToken } from './tokens.actions'; import { TokensStateModel } from './tokens.models'; @State({ @@ -34,7 +27,7 @@ export class TokensState { return this.tokensService.getScopes().pipe( tap((scopes) => { ctx.patchState({ scopes }); - }), + }) ); } @@ -43,16 +36,14 @@ export class TokensState { return this.tokensService.getTokens().pipe( tap((tokens) => { ctx.patchState({ tokens }); - }), + }) ); } @Action(GetTokenById) getTokenById(ctx: StateContext, action: GetTokenById) { const state = ctx.getState(); - const tokenFromState = state.tokens.find( - (token: Token) => token.id === action.tokenId, - ); + const tokenFromState = state.tokens.find((token: Token) => token.id === action.tokenId); if (tokenFromState) { return of(tokenFromState); @@ -62,23 +53,19 @@ export class TokensState { tap((token) => { const updatedTokens = [...state.tokens, token]; ctx.patchState({ tokens: updatedTokens }); - }), + }) ); } @Action(UpdateToken) updateToken(ctx: StateContext, action: UpdateToken) { - return this.tokensService - .updateToken(action.tokenId, action.name, action.scopes) - .pipe( - tap((updatedToken) => { - const state = ctx.getState(); - const updatedTokens = state.tokens.map((token: Token) => - token.id === action.tokenId ? updatedToken : token, - ); - ctx.patchState({ tokens: updatedTokens }); - }), - ); + return this.tokensService.updateToken(action.tokenId, action.name, action.scopes).pipe( + tap((updatedToken) => { + const state = ctx.getState(); + const updatedTokens = state.tokens.map((token: Token) => (token.id === action.tokenId ? updatedToken : token)); + ctx.patchState({ tokens: updatedTokens }); + }) + ); } @Action(DeleteToken) @@ -86,11 +73,9 @@ export class TokensState { return this.tokensService.deleteToken(action.tokenId).pipe( tap(() => { const state = ctx.getState(); - const updatedTokens = state.tokens.filter( - (token: Token) => token.id !== action.tokenId, - ); + const updatedTokens = state.tokens.filter((token: Token) => token.id !== action.tokenId); ctx.patchState({ tokens: updatedTokens }); - }), + }) ); } @@ -103,7 +88,7 @@ export class TokensState { ctx.patchState({ tokens: updatedTokens }); return newToken; - }), + }) ); } } diff --git a/src/app/features/settings/tokens/token-add-edit-form/token-add-edit-form.component.html b/src/app/features/settings/tokens/token-add-edit-form/token-add-edit-form.component.html index a0199a5c1..f6a2a10f3 100644 --- a/src/app/features/settings/tokens/token-add-edit-form/token-add-edit-form.component.html +++ b/src/app/features/settings/tokens/token-add-edit-form/token-add-edit-form.component.html @@ -1,39 +1,23 @@ -
+
- - + +

- {{ "settings.tokens.form.scopes.title" | translate }} + {{ 'settings.tokens.form.scopes.title' | translate }}

- {{ "settings.tokens.form.scopes.description" | translate }} + {{ 'settings.tokens.form.scopes.description' | translate }}

@for (scope of tokenScopes(); track scope.id) {
- +
@@ -81,28 +67,21 @@

- +
{ return this.projects().map((project) => ({ @@ -103,26 +83,20 @@ export class AddProjectFormComponent implements OnInit { }); constructor() { - this.projectForm - .get(ProjectFormControls.Template) - ?.valueChanges.subscribe((value) => { - this.hasTemplateSelected.set(!!value); - }); + this.projectForm.get(ProjectFormControls.Template)?.valueChanges.subscribe((value) => { + this.hasTemplateSelected.set(!!value); + }); } ngOnInit(): void { - this.#store.dispatch( - new GetMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {}), - ); + this.#store.dispatch(new GetMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {})); this.selectAllAffiliations(); } selectAllAffiliations(): void { const allAffiliationValues = this.affiliations().map((aff) => aff.id); - this.projectForm - .get(ProjectFormControls.Affiliations) - ?.setValue(allAffiliationValues); + this.projectForm.get(ProjectFormControls.Affiliations)?.setValue(allAffiliationValues); } removeAllAffiliations(): void { @@ -145,14 +119,12 @@ export class AddProjectFormComponent implements OnInit { formValue.description, formValue.template, formValue.storageLocation, - formValue.affiliations, - ), + formValue.affiliations + ) ) .subscribe({ next: () => { - this.#store.dispatch( - new GetMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {}), - ); + this.#store.dispatch(new GetMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {})); this.dialogRef.close(); }, error: (error) => { diff --git a/src/app/shared/components/my-projects-table/my-projects-table.component.html b/src/app/shared/components/my-projects-table/my-projects-table.component.html index cacd769fe..406b6807e 100644 --- a/src/app/shared/components/my-projects-table/my-projects-table.component.html +++ b/src/app/shared/components/my-projects-table/my-projects-table.component.html @@ -9,12 +9,12 @@ - {{ "myProjects.table.columns.title" | translate }} + {{ 'myProjects.table.columns.title' | translate }} - {{ "myProjects.table.columns.contributors" | translate }} + {{ 'myProjects.table.columns.contributors' | translate }} - {{ "myProjects.table.columns.modified" | translate }} + {{ 'myProjects.table.columns.modified' | translate }} @@ -51,12 +51,12 @@ - {{ "myProjects.table.columns.title" | translate }} + {{ 'myProjects.table.columns.title' | translate }} - {{ "myProjects.table.columns.contributors" | translate }} + {{ 'myProjects.table.columns.contributors' | translate }} - {{ "myProjects.table.columns.modified" | translate }} + {{ 'myProjects.table.columns.modified' | translate }} @@ -65,20 +65,16 @@

- + {{ item.title }}

@for (contributor of item.contributors; track contributor) { - {{ contributor.fullName }}{{ $last ? "" : ", " }} + {{ contributor.fullName }}{{ $last ? '' : ', ' }} } - {{ item.dateModified | date: "MMM d, y, h:mm a" }} + {{ item.dateModified | date: 'MMM d, y, h:mm a' }}
diff --git a/src/app/shared/components/my-projects-table/my-projects-table.component.ts b/src/app/shared/components/my-projects-table/my-projects-table.component.ts index 1970db99d..8694647eb 100644 --- a/src/app/shared/components/my-projects-table/my-projects-table.component.ts +++ b/src/app/shared/components/my-projects-table/my-projects-table.component.ts @@ -5,12 +5,7 @@ import { Skeleton } from 'primeng/skeleton'; import { TableModule, TablePageEvent } from 'primeng/table'; import { CommonModule } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - input, - output, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, input, output } from '@angular/core'; import { MyProjectsItem } from '@osf/features/my-projects/entities/my-projects.entities'; import { SearchInputComponent } from '@shared/components/search-input/search-input.component'; @@ -20,13 +15,7 @@ import { SortOrder } from '@shared/utils/sort-order.enum'; @Component({ selector: 'osf-my-projects-table', standalone: true, - imports: [ - CommonModule, - TableModule, - SearchInputComponent, - Skeleton, - TranslatePipe, - ], + imports: [CommonModule, TableModule, SearchInputComponent, Skeleton, TranslatePipe], templateUrl: './my-projects-table.component.html', styleUrl: './my-projects-table.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/shared/components/password-input-hint/password-input-hint.component.html b/src/app/shared/components/password-input-hint/password-input-hint.component.html index 3c337a022..028698b23 100644 --- a/src/app/shared/components/password-input-hint/password-input-hint.component.html +++ b/src/app/shared/components/password-input-hint/password-input-hint.component.html @@ -1,3 +1,3 @@ - {{ "auth.common.password.requirements" | translate }} + {{ 'auth.common.password.requirements' | translate }} diff --git a/src/app/shared/components/resources/filter-chips/filter-chips.component.html b/src/app/shared/components/resources/filter-chips/filter-chips.component.html index 4d6ec44a7..b55a1cba0 100644 --- a/src/app/shared/components/resources/filter-chips/filter-chips.component.html +++ b/src/app/shared/components/resources/filter-chips/filter-chips.component.html @@ -1,5 +1,5 @@ @if (filters().creator.value && !isMyProfilePage()) { - @let creator = filters().creator.filterName + ": " + filters().creator.label; + @let creator = filters().creator.filterName + ': ' + filters().creator.label;
- @if ( - item()?.resourceType && item()?.resourceType === ResourceType.Agent - ) { + @if (item()?.resourceType && item()?.resourceType === ResourceType.Agent) {

User

} @else if (item()?.resourceType) {

{{ ResourceType[item()?.resourceType!] }}

}
- @if ( - item()?.resourceType === ResourceType.File && item()?.fileName - ) { + @if (item()?.resourceType === ResourceType.File && item()?.fileName) { {{ item()?.fileName }} } @else if (item()?.title && item()?.title) { {{ item()?.title }} } @if (item()?.orcid) { - orcid + orcid }
@if (item()?.creators?.length) {
- @for ( - creator of item()?.creators!.slice(0, 4); - track creator.id; - let i = $index - ) { + @for (creator of item()?.creators!.slice(0, 4); track creator.id; let i = $index) { {{ creator.name }} @if (i < (item()?.creators)!.length - 1 && i < 3) { , } } @if ((item()?.creators)!.length > 4) { -

-  and {{ (item()?.creators)!.length - 4 }} more -

+

 and {{ (item()?.creators)!.length - 4 }} more

}
} @@ -54,25 +39,21 @@ @if (item()?.from?.id && item()?.from?.name) { } @if (item()?.dateCreated && item()?.dateModified) {

@if (!isSmall()) { - Date created: {{ item()?.dateCreated | date: "MMMM d, y" }} | - Date modified: {{ item()?.dateModified | date: "MMMM d, y" }} + Date created: {{ item()?.dateCreated | date: 'MMMM d, y' }} | Date modified: + {{ item()?.dateModified | date: 'MMMM d, y' }} } @else {

-

- Date created: {{ item()?.dateCreated | date: "MMMM d, y" }} -

+

Date created: {{ item()?.dateCreated | date: 'MMMM d, y' }}

Date modified: - {{ item()?.dateModified | date: "MMMM d, y" }} + {{ item()?.dateModified | date: 'MMMM d, y' }}

} @@ -146,9 +127,7 @@ } @if (item()?.registrationTemplate) { -

- Registration Template: {{ item()?.registrationTemplate }} -

+

Registration Template: {{ item()?.registrationTemplate }}

} @if (item()?.provider?.id) { @@ -158,14 +137,8 @@ } - @if ( - item()?.conflictOfInterestResponse && - item()?.conflictOfInterestResponse === "no-conflict-of-interest" - ) { -

- Conflict of Interest response: Author asserted no Conflict of - Interest -

+ @if (item()?.conflictOfInterestResponse && item()?.conflictOfInterestResponse === 'no-conflict-of-interest') { +

Conflict of Interest response: Author asserted no Conflict of Interest

} @if (item()?.resourceType !== ResourceType.Agent && item()?.id) { @@ -189,9 +162,7 @@ } @else {

Public projects: {{ item()?.publicProjects ?? 0 }}

-

- Public registrations: {{ item()?.publicRegistrations ?? 0 }} -

+

Public registrations: {{ item()?.publicRegistrations ?? 0 }}

Public preprints: {{ item()?.publicPreprints ?? 0 }}

} } diff --git a/src/app/shared/components/resources/resource-card/resource-card.component.ts b/src/app/shared/components/resources/resource-card/resource-card.component.ts index 04a63b20a..009c158f6 100644 --- a/src/app/shared/components/resources/resource-card/resource-card.component.ts +++ b/src/app/shared/components/resources/resource-card/resource-card.component.ts @@ -1,20 +1,10 @@ -import { - Accordion, - AccordionContent, - AccordionHeader, - AccordionPanel, -} from 'primeng/accordion'; +import { Accordion, AccordionContent, AccordionHeader, AccordionPanel } from 'primeng/accordion'; import { Skeleton } from 'primeng/skeleton'; import { finalize } from 'rxjs'; import { DatePipe, NgOptimizedImage } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - inject, - model, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject, model } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { Resource } from '@osf/features/search/models/resource.entity'; @@ -24,15 +14,7 @@ import { ResourceCardService } from '@shared/components/resources/resource-card/ @Component({ selector: 'osf-resource-card', - imports: [ - Accordion, - AccordionContent, - AccordionHeader, - AccordionPanel, - DatePipe, - NgOptimizedImage, - Skeleton, - ], + imports: [Accordion, AccordionContent, AccordionHeader, AccordionPanel, DatePipe, NgOptimizedImage, Skeleton], templateUrl: './resource-card.component.html', styleUrl: './resource-card.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -57,7 +39,7 @@ export class ResourceCardComponent { finalize(() => { this.loading = false; this.dataIsLoaded = true; - }), + }) ) .subscribe((res) => { this.item.update( @@ -69,7 +51,7 @@ export class ResourceCardComponent { publicRegistrations: res.registrations, education: res.education, employment: res.employment, - }) as Resource, + }) as Resource ); }); } diff --git a/src/app/shared/components/resources/resource-filters/filters/creators/creators-filter.component.ts b/src/app/shared/components/resources/resource-filters/filters/creators/creators-filter.component.ts index 427411116..b9305ecef 100644 --- a/src/app/shared/components/resources/resource-filters/filters/creators/creators-filter.component.ts +++ b/src/app/shared/components/resources/resource-filters/filters/creators/creators-filter.component.ts @@ -22,10 +22,7 @@ import { GetCreatorsOptions, } from '@shared/components/resources/resource-filters/filters/store/resource-filters-options.actions'; import { ResourceFiltersOptionsSelectors } from '@shared/components/resources/resource-filters/filters/store/resource-filters-options.selectors'; -import { - ResourceFiltersSelectors, - SetCreator, -} from '@shared/components/resources/resource-filters/store'; +import { ResourceFiltersSelectors, SetCreator } from '@shared/components/resources/resource-filters/store'; @Component({ selector: 'osf-creators-filter', @@ -37,9 +34,7 @@ import { export class CreatorsFilterComponent implements OnDestroy { readonly #store = inject(Store); - protected searchCreatorsResults = this.#store.selectSignal( - ResourceFiltersOptionsSelectors.getCreators, - ); + protected searchCreatorsResults = this.#store.selectSignal(ResourceFiltersOptionsSelectors.getCreators); protected creatorsOptions = computed(() => { return this.searchCreatorsResults().map((creator) => ({ label: creator.name, @@ -47,20 +42,14 @@ export class CreatorsFilterComponent implements OnDestroy { })); }); protected creatorsLoading = signal(false); - protected creatorState = this.#store.selectSignal( - ResourceFiltersSelectors.getCreator, - ); + protected creatorState = this.#store.selectSignal(ResourceFiltersSelectors.getCreator); readonly #unsubscribe = new Subject(); protected creatorsInput = signal(null); protected initialization = true; constructor() { toObservable(this.creatorsInput) - .pipe( - debounceTime(500), - distinctUntilChanged(), - takeUntil(this.#unsubscribe), - ) + .pipe(debounceTime(500), distinctUntilChanged(), takeUntil(this.#unsubscribe)) .subscribe((searchText) => { if (!this.initialization) { if (searchText) { @@ -94,9 +83,7 @@ export class CreatorsFilterComponent implements OnDestroy { setCreator(event: SelectChangeEvent): void { if ((event.originalEvent as PointerEvent).pointerId && event.value) { - const creator = this.creatorsOptions().find((p) => - p.label.includes(event.value), - ); + const creator = this.creatorsOptions().find((p) => p.label.includes(event.value)); if (creator) { this.#store.dispatch(new SetCreator(creator.label, creator.id)); this.#store.dispatch(GetAllOptions); diff --git a/src/app/shared/components/resources/resource-filters/filters/date-created/date-created-filter.component.ts b/src/app/shared/components/resources/resource-filters/filters/date-created/date-created-filter.component.ts index 5bd2ee659..3b0b094c0 100644 --- a/src/app/shared/components/resources/resource-filters/filters/date-created/date-created-filter.component.ts +++ b/src/app/shared/components/resources/resource-filters/filters/date-created/date-created-filter.component.ts @@ -2,23 +2,12 @@ import { Store } from '@ngxs/store'; import { Select, SelectChangeEvent } from 'primeng/select'; -import { - ChangeDetectionStrategy, - Component, - computed, - effect, - inject, - signal, - untracked, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, effect, inject, signal, untracked } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { GetAllOptions } from '@shared/components/resources/resource-filters/filters/store/resource-filters-options.actions'; import { ResourceFiltersOptionsSelectors } from '@shared/components/resources/resource-filters/filters/store/resource-filters-options.selectors'; -import { - ResourceFiltersSelectors, - SetDateCreated, -} from '@shared/components/resources/resource-filters/store'; +import { ResourceFiltersSelectors, SetDateCreated } from '@shared/components/resources/resource-filters/store'; @Component({ selector: 'osf-date-created-filter', @@ -30,12 +19,8 @@ import { export class DateCreatedFilterComponent { readonly #store = inject(Store); - protected availableDates = this.#store.selectSignal( - ResourceFiltersOptionsSelectors.getDatesCreated, - ); - protected dateCreatedState = this.#store.selectSignal( - ResourceFiltersSelectors.getDateCreated, - ); + protected availableDates = this.#store.selectSignal(ResourceFiltersOptionsSelectors.getDatesCreated); + protected dateCreatedState = this.#store.selectSignal(ResourceFiltersSelectors.getDateCreated); protected inputDate = signal(null); protected datesOptions = computed(() => { return this.availableDates().map((date) => ({ diff --git a/src/app/shared/components/resources/resource-filters/filters/funder/funder-filter.component.html b/src/app/shared/components/resources/resource-filters/filters/funder/funder-filter.component.html index fd813ff38..f2bba5e1f 100644 --- a/src/app/shared/components/resources/resource-filters/filters/funder/funder-filter.component.html +++ b/src/app/shared/components/resources/resource-filters/filters/funder/funder-filter.component.html @@ -1,7 +1,5 @@

diff --git a/src/app/shared/components/sub-header/sub-header.component.ts b/src/app/shared/components/sub-header/sub-header.component.ts index 9bb3a75a0..a7bb0c5f4 100644 --- a/src/app/shared/components/sub-header/sub-header.component.ts +++ b/src/app/shared/components/sub-header/sub-header.component.ts @@ -1,12 +1,6 @@ import { Button } from 'primeng/button'; -import { - ChangeDetectionStrategy, - Component, - inject, - input, - output, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject, input, output } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { IS_XSMALL } from '@shared/utils/breakpoints.tokens'; diff --git a/src/app/shared/utils/breakpoints.tokens.ts b/src/app/shared/utils/breakpoints.tokens.ts index 14ab29fc7..bb492746e 100644 --- a/src/app/shared/utils/breakpoints.tokens.ts +++ b/src/app/shared/utils/breakpoints.tokens.ts @@ -5,16 +5,12 @@ import { inject, InjectionToken } from '@angular/core'; import { BreakpointQueries } from '@shared/utils/breakpoint-queries.enum'; -function createBreakpointToken( - query: string, -): InjectionToken> { +function createBreakpointToken(query: string): InjectionToken> { return new InjectionToken>(`Breakpoint ${query}`, { providedIn: 'root', factory: () => { const breakpointObserver = inject(BreakpointObserver); - return breakpointObserver - .observe([query]) - .pipe(map((result) => result.matches)); + return breakpointObserver.observe([query]).pipe(map((result) => result.matches)); }, }); } diff --git a/src/app/shared/utils/remove-nullable.const.ts b/src/app/shared/utils/remove-nullable.const.ts index 275cc9d2f..615efe166 100644 --- a/src/app/shared/utils/remove-nullable.const.ts +++ b/src/app/shared/utils/remove-nullable.const.ts @@ -1,7 +1,5 @@ export function removeNullable(obj: T): Partial { return Object.fromEntries( - Object.entries(obj).filter( - ([_, value]) => value !== null && value !== undefined, - ), + Object.entries(obj).filter(([_, value]) => value !== null && value !== undefined) ) as Partial; } diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index dd210bfe0..ae8c84dd1 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -482,4 +482,4 @@ }, "copyright": "Copyright © 2011-2025" } -} \ No newline at end of file +} diff --git a/src/assets/icons/dist/icons.css b/src/assets/icons/dist/icons.css index d414d65b9..9c40a6bbb 100644 --- a/src/assets/icons/dist/icons.css +++ b/src/assets/icons/dist/icons.css @@ -1,222 +1,224 @@ @font-face { - font-family: "icons"; - src: url("./icons.eot?cdc3c964cbe66b7f705386b7b66a51b6#iefix") format("embedded-opentype"), -url("./icons.woff2?cdc3c964cbe66b7f705386b7b66a51b6") format("woff2"), -url("./icons.woff?cdc3c964cbe66b7f705386b7b66a51b6") format("woff"); + font-family: 'icons'; + src: + url('./icons.eot?cdc3c964cbe66b7f705386b7b66a51b6#iefix') format('embedded-opentype'), + url('./icons.woff2?cdc3c964cbe66b7f705386b7b66a51b6') format('woff2'), + url('./icons.woff?cdc3c964cbe66b7f705386b7b66a51b6') format('woff'); } -i[class^="osf-icon-"]:before, i[class*=" osf-icon-"]:before { - font-family: icons !important; - font-style: normal; - font-weight: normal !important; - font-variant: normal; - text-transform: none; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; +i[class^='osf-icon-']:before, +i[class*=' osf-icon-']:before { + font-family: icons !important; + font-style: normal; + font-weight: normal !important; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } .osf-icon-withdrawn:before { - content: "\f101"; + content: '\f101'; } .osf-icon-warning:before { - content: "\f102"; + content: '\f102'; } .osf-icon-warning-sign:before { - content: "\f103"; + content: '\f103'; } .osf-icon-upload:before { - content: "\f104"; + content: '\f104'; } .osf-icon-trash:before { - content: "\f105"; + content: '\f105'; } .osf-icon-support:before { - content: "\f106"; + content: '\f106'; } .osf-icon-supplements:before { - content: "\f107"; + content: '\f107'; } .osf-icon-sort-desc:before { - content: "\f108"; + content: '\f108'; } .osf-icon-sort-asc:before { - content: "\f109"; + content: '\f109'; } .osf-icon-sort-asc-grey:before { - content: "\f10a"; + content: '\f10a'; } .osf-icon-share:before { - content: "\f10b"; + content: '\f10b'; } .osf-icon-settings:before { - content: "\f10c"; + content: '\f10c'; } .osf-icon-search:before { - content: "\f10d"; + content: '\f10d'; } .osf-icon-search-2:before { - content: "\f10e"; + content: '\f10e'; } .osf-icon-rejected:before { - content: "\f10f"; + content: '\f10f'; } .osf-icon-registries:before { - content: "\f110"; + content: '\f110'; } .osf-icon-quotes:before { - content: "\f111"; + content: '\f111'; } .osf-icon-profile:before { - content: "\f112"; + content: '\f112'; } .osf-icon-preprints:before { - content: "\f113"; + content: '\f113'; } .osf-icon-plus:before { - content: "\f114"; + content: '\f114'; } .osf-icon-pending:before { - content: "\f115"; + content: '\f115'; } .osf-icon-pdf:before { - content: "\f116"; + content: '\f116'; } .osf-icon-papers:before { - content: "\f117"; + content: '\f117'; } .osf-icon-padlock:before { - content: "\f118"; + content: '\f118'; } .osf-icon-padlock-unlock:before { - content: "\f119"; + content: '\f119'; } .osf-icon-my-projects:before { - content: "\f11a"; + content: '\f11a'; } .osf-icon-minus:before { - content: "\f11b"; + content: '\f11b'; } .osf-icon-menu:before { - content: "\f11c"; + content: '\f11c'; } .osf-icon-meetings:before { - content: "\f11d"; + content: '\f11d'; } .osf-icon-materials:before { - content: "\f11e"; + content: '\f11e'; } .osf-icon-list:before { - content: "\f11f"; + content: '\f11f'; } .osf-icon-link:before { - content: "\f120"; + content: '\f120'; } .osf-icon-last:before { - content: "\f121"; + content: '\f121'; } .osf-icon-institutions:before { - content: "\f122"; + content: '\f122'; } .osf-icon-information:before { - content: "\f123"; + content: '\f123'; } .osf-icon-image:before { - content: "\f124"; + content: '\f124'; } .osf-icon-home:before { - content: "\f125"; + content: '\f125'; } .osf-icon-home-2:before { - content: "\f126"; + content: '\f126'; } .osf-icon-help:before { - content: "\f127"; + content: '\f127'; } .osf-icon-folder:before { - content: "\f128"; + content: '\f128'; } .osf-icon-first:before { - content: "\f129"; + content: '\f129'; } .osf-icon-filter:before { - content: "\f12a"; + content: '\f12a'; } .osf-icon-eye-view:before { - content: "\f12b"; + content: '\f12b'; } .osf-icon-eye-hidden:before { - content: "\f12c"; + content: '\f12c'; } .osf-icon-email:before { - content: "\f12d"; + content: '\f12d'; } .osf-icon-duplicate:before { - content: "\f12e"; + content: '\f12e'; } .osf-icon-download:before { - content: "\f12f"; + content: '\f12f'; } .osf-icon-double-arrow-left:before { - content: "\f130"; + content: '\f130'; } .osf-icon-dots:before { - content: "\f131"; + content: '\f131'; } .osf-icon-donate:before { - content: "\f132"; + content: '\f132'; } .osf-icon-doc:before { - content: "\f133"; + content: '\f133'; } .osf-icon-diagram:before { - content: "\f134"; + content: '\f134'; } .osf-icon-data:before { - content: "\f135"; + content: '\f135'; } .osf-icon-customize:before { - content: "\f136"; + content: '\f136'; } .osf-icon-copy:before { - content: "\f137"; + content: '\f137'; } .osf-icon-contact:before { - content: "\f138"; + content: '\f138'; } .osf-icon-collections:before { - content: "\f139"; + content: '\f139'; } .osf-icon-code:before { - content: "\f13a"; + content: '\f13a'; } .osf-icon-close:before { - content: "\f13b"; + content: '\f13b'; } .osf-icon-chevron-right:before { - content: "\f13c"; + content: '\f13c'; } .osf-icon-chevron-left:before { - content: "\f13d"; + content: '\f13d'; } .osf-icon-calendar-silhouette:before { - content: "\f13e"; + content: '\f13e'; } .osf-icon-bookmark:before { - content: "\f13f"; + content: '\f13f'; } .osf-icon-bookmark-fill:before { - content: "\f140"; + content: '\f140'; } .osf-icon-arrow:before { - content: "\f141"; + content: '\f141'; } .osf-icon-arrow-left:before { - content: "\f142"; + content: '\f142'; } .osf-icon-arrow-down:before { - content: "\f143"; + content: '\f143'; } .osf-icon-accepted:before { - content: "\f144"; + content: '\f144'; } diff --git a/src/assets/icons/dist/icons.json b/src/assets/icons/dist/icons.json index 409477e4c..34e334f6b 100644 --- a/src/assets/icons/dist/icons.json +++ b/src/assets/icons/dist/icons.json @@ -1,70 +1,70 @@ { - "withdrawn": 61697, - "warning": 61698, - "warning-sign": 61699, - "upload": 61700, - "trash": 61701, - "support": 61702, - "supplements": 61703, - "sort-desc": 61704, - "sort-asc": 61705, - "sort-asc-grey": 61706, - "share": 61707, - "settings": 61708, - "search": 61709, - "search-2": 61710, - "rejected": 61711, - "registries": 61712, - "quotes": 61713, - "profile": 61714, - "preprints": 61715, - "plus": 61716, - "pending": 61717, - "pdf": 61718, - "papers": 61719, - "padlock": 61720, - "padlock-unlock": 61721, - "my-projects": 61722, - "minus": 61723, - "menu": 61724, - "meetings": 61725, - "materials": 61726, - "list": 61727, - "link": 61728, - "last": 61729, - "institutions": 61730, - "information": 61731, - "image": 61732, - "home": 61733, - "home-2": 61734, - "help": 61735, - "folder": 61736, - "first": 61737, - "filter": 61738, - "eye-view": 61739, - "eye-hidden": 61740, - "email": 61741, - "duplicate": 61742, - "download": 61743, - "double-arrow-left": 61744, - "dots": 61745, - "donate": 61746, - "doc": 61747, - "diagram": 61748, - "data": 61749, - "customize": 61750, - "copy": 61751, - "contact": 61752, - "collections": 61753, - "code": 61754, - "close": 61755, - "chevron-right": 61756, - "chevron-left": 61757, - "calendar-silhouette": 61758, - "bookmark": 61759, - "bookmark-fill": 61760, - "arrow": 61761, - "arrow-left": 61762, - "arrow-down": 61763, - "accepted": 61764 -} \ No newline at end of file + "withdrawn": 61697, + "warning": 61698, + "warning-sign": 61699, + "upload": 61700, + "trash": 61701, + "support": 61702, + "supplements": 61703, + "sort-desc": 61704, + "sort-asc": 61705, + "sort-asc-grey": 61706, + "share": 61707, + "settings": 61708, + "search": 61709, + "search-2": 61710, + "rejected": 61711, + "registries": 61712, + "quotes": 61713, + "profile": 61714, + "preprints": 61715, + "plus": 61716, + "pending": 61717, + "pdf": 61718, + "papers": 61719, + "padlock": 61720, + "padlock-unlock": 61721, + "my-projects": 61722, + "minus": 61723, + "menu": 61724, + "meetings": 61725, + "materials": 61726, + "list": 61727, + "link": 61728, + "last": 61729, + "institutions": 61730, + "information": 61731, + "image": 61732, + "home": 61733, + "home-2": 61734, + "help": 61735, + "folder": 61736, + "first": 61737, + "filter": 61738, + "eye-view": 61739, + "eye-hidden": 61740, + "email": 61741, + "duplicate": 61742, + "download": 61743, + "double-arrow-left": 61744, + "dots": 61745, + "donate": 61746, + "doc": 61747, + "diagram": 61748, + "data": 61749, + "customize": 61750, + "copy": 61751, + "contact": 61752, + "collections": 61753, + "code": 61754, + "close": 61755, + "chevron-right": 61756, + "chevron-left": 61757, + "calendar-silhouette": 61758, + "bookmark": 61759, + "bookmark-fill": 61760, + "arrow": 61761, + "arrow-left": 61762, + "arrow-down": 61763, + "accepted": 61764 +} diff --git a/src/assets/icons/optimize.mjs b/src/assets/icons/optimize.mjs index 1848be4b1..58e4c0caf 100644 --- a/src/assets/icons/optimize.mjs +++ b/src/assets/icons/optimize.mjs @@ -15,7 +15,6 @@ const removeFillAttribute = (svgString) => { fs.promises .readdir(path.join(__dirname, sourceDirectory)) .then((files) => { - files.forEach((file) => { if (file.endsWith('.svg')) { console.log(file); diff --git a/src/assets/styles/_variables.scss b/src/assets/styles/_variables.scss index 7c96b0206..9cff6f9af 100644 --- a/src/assets/styles/_variables.scss +++ b/src/assets/styles/_variables.scss @@ -128,10 +128,5 @@ $white-60: var(--white-60); rgba(219, 237, 251, 0.5) 98.07% ), #f3f8fd; - --gradient-3: linear-gradient( - 90.12deg, - #dbedfb 0.03%, - #eff4fc 54.38%, - #dbedfb 98.07% - ); + --gradient-3: linear-gradient(90.12deg, #dbedfb 0.03%, #eff4fc 54.38%, #dbedfb 98.07%); } diff --git a/src/assets/styles/overrides/panel-menu.scss b/src/assets/styles/overrides/panel-menu.scss index 7b72cdd48..a9fa7913d 100644 --- a/src/assets/styles/overrides/panel-menu.scss +++ b/src/assets/styles/overrides/panel-menu.scss @@ -36,8 +36,7 @@ background-color: transparent; } - .p-panelmenu-header:not(.p-disabled):focus-visible - .p-panelmenu-header-content, + .p-panelmenu-header:not(.p-disabled):focus-visible .p-panelmenu-header-content, .p-panelmenu-item.p-focus > .p-panelmenu-item-content { background-color: var.$dark-blue-2; border-radius: 0.5rem; diff --git a/src/index.html b/src/index.html index 0628ad111..c7a2695f3 100644 --- a/src/index.html +++ b/src/index.html @@ -10,8 +10,6 @@ - + diff --git a/src/main.ts b/src/main.ts index 6ad6b3a1c..bd61a1937 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,16 +1,8 @@ -import { isDevMode } from '@angular/core'; import { bootstrapApplication } from '@angular/platform-browser'; -import { provideServiceWorker } from '@angular/service-worker'; import { AppComponent } from '@osf/app.component'; import { appConfig } from '@osf/app.config'; bootstrapApplication(AppComponent, { - providers: [ - ...appConfig.providers, - provideServiceWorker('ngsw-worker.js', { - enabled: !isDevMode(), - registrationStrategy: 'registerWhenStable:30000', - }), - ], + providers: [...appConfig.providers], }).catch((err) => console.error(err)); diff --git a/tsconfig.app.json b/tsconfig.app.json index 3775b37e3..8886e903f 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -6,10 +6,6 @@ "outDir": "./out-tsc/app", "types": [] }, - "files": [ - "src/main.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 5fb748d92..e00e30e6d 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -4,12 +4,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", - "types": [ - "jasmine" - ] + "types": ["jasmine"] }, - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] }