diff --git a/app/settings/addons/controller.ts b/app/settings/addons/controller.ts new file mode 100644 index 00000000000..488b2e85900 --- /dev/null +++ b/app/settings/addons/controller.ts @@ -0,0 +1,8 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +import CurrentUser from 'ember-osf-web/services/current-user'; + +export default class SettingsAddonsController extends Controller { + @service currentUser!: CurrentUser; +} diff --git a/app/settings/addons/route.ts b/app/settings/addons/route.ts new file mode 100644 index 00000000000..ce5c7df8022 --- /dev/null +++ b/app/settings/addons/route.ts @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class SettingsAddonsRoute extends Route { +} diff --git a/app/settings/addons/template.hbs b/app/settings/addons/template.hbs index e69de29bb2d..6987cbe114d 100644 --- a/app/settings/addons/template.hbs +++ b/app/settings/addons/template.hbs @@ -0,0 +1,16 @@ + + {{#if manager.currentListIsLoading}} + + {{else}} + {{#each manager.filteredAddonProviders as |provider|}} +
+ {{provider.name}} +
+ {{else}} + {{t 'addons.list.no-results'}} + {{/each}} + {{/if}} +
diff --git a/lib/osf-components/addon/components/addons-service/manager/component.ts b/lib/osf-components/addon/components/addons-service/manager/component.ts index a533e6ed0d3..30544712bb1 100644 --- a/lib/osf-components/addon/components/addons-service/manager/component.ts +++ b/lib/osf-components/addon/components/addons-service/manager/component.ts @@ -31,7 +31,7 @@ enum PageMode { CONFIGURE = 'configure', } -enum FilterTypes { +export enum FilterTypes { STORAGE = 'additional-storage', CITATION_MANAGER = 'citation-manager', CLOUD_COMPUTING = 'cloud-computing', diff --git a/lib/osf-components/addon/components/addons-service/user-addons-manager/component.ts b/lib/osf-components/addon/components/addons-service/user-addons-manager/component.ts new file mode 100644 index 00000000000..0d2f446e9e1 --- /dev/null +++ b/lib/osf-components/addon/components/addons-service/user-addons-manager/component.ts @@ -0,0 +1,138 @@ +import EmberArray, { A } from '@ember/array'; +import { inject as service } from '@ember/service'; +import { waitFor } from '@ember/test-waiters'; +import Store from '@ember-data/store'; +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { task } from 'ember-concurrency'; +import { taskFor } from 'ember-concurrency-ts'; +import IntlService from 'ember-intl/services/intl'; + +import UserReferenceModel from 'ember-osf-web/models/user-reference'; +import Provider from 'ember-osf-web/packages/addons-service/provider'; +import CurrentUserService from 'ember-osf-web/services/current-user'; +import AuthorizedStorageAccountModel from 'ember-osf-web/models/authorized-storage-account'; +import UserModel from 'ember-osf-web/models/user'; + +import ExternalStorageServiceModel from 'ember-osf-web/models/external-storage-service'; +import CloudComputingServiceModel from 'ember-osf-web/models/cloud-computing-service'; +import CitationServiceModel from 'ember-osf-web/models/citation-service'; + +import { FilterTypes } from '../manager/component'; + +type AllProviderTypes = ExternalStorageServiceModel | CloudComputingServiceModel | CitationServiceModel; + +interface Args { + user: UserModel; +} + +export default class UserAddonManagerComponent extends Component { + @service store!: Store; + @service currentUser!: CurrentUserService; + @service intl!: IntlService; + + user = this.args.user; + @tracked userReference?: UserReferenceModel; + + filterTypeMapper = { + [FilterTypes.STORAGE]: { + modelName: 'external-storage-service', + userRelationshipName: 'authorizedStorageAccounts', + fetchProvidersTask: taskFor(this.getStorageAddonProviders), + list: A([]) as EmberArray, + authorizedAccounts: A([]) as EmberArray, + }, + [FilterTypes.CITATION_MANAGER]: { + modelName: 'citation-service', + fetchProvidersTask: taskFor(this.getCitationAddonProviders), + list: A([]) as EmberArray, + // TODO: add authorizedAccounts for citation manager + }, + [FilterTypes.CLOUD_COMPUTING]: { + modelName: 'cloud-service', + fetchProvidersTask: taskFor(this.getCloudComputingProviders), + list: A([]) as EmberArray, + // TODO: add authorizedAccounts for cloud computing + }, + }; + @tracked activeFilterType = FilterTypes.STORAGE; + + @tracked selectedProvider?: Provider; + @tracked selectedAccount?: AuthorizedStorageAccountModel; + + + get filteredAddonProviders() { + return this.filterTypeMapper[this.activeFilterType].list; + } + + get currentListIsLoading() { + const activeFilterObject = this.filterTypeMapper[this.activeFilterType]; + return activeFilterObject.fetchProvidersTask.isRunning; + } + + + constructor(owner: unknown, args: Args) { + super(owner, args); + taskFor(this.getUserReference).perform(); + taskFor(this.getStorageAddonProviders).perform(); + taskFor(this.getAuthorizedStorageAccounts).perform(); + } + + @task + @waitFor + async getUserReference() { + const { user } = this; + const userReference = await this.store.findRecord('user-reference', user.id); + this.userReference = userReference; + } + + @task + @waitFor + async getAuthorizedStorageAccounts() { + const { userReference } = this; + const mappedObject = this.filterTypeMapper[FilterTypes.STORAGE]; + if (userReference) { + const accounts = (await userReference.authorizedStorageAccounts).toArray(); + mappedObject.authorizedAccounts = accounts; + } + } + + @task + @waitFor + async getStorageAddonProviders() { + const activeFilterObject = this.filterTypeMapper[FilterTypes.STORAGE]; + const serviceStorageProviders: AllProviderTypes[] = + await taskFor(this.getExternalProviders).perform(activeFilterObject.modelName); + const sortedList = serviceStorageProviders.sort(this.providerSorter); + activeFilterObject.list = sortedList; + } + + @task + @waitFor + async getCloudComputingProviders() { + const activeFilterObject = this.filterTypeMapper[FilterTypes.CLOUD_COMPUTING]; + const cloudComputingProviders: AllProviderTypes[] = + await taskFor(this.getExternalProviders).perform(activeFilterObject.modelName); + activeFilterObject.list = cloudComputingProviders.sort(this.providerSorter); + } + + @task + @waitFor + async getCitationAddonProviders() { + const activeFilterObject = this.filterTypeMapper[FilterTypes.CITATION_MANAGER]; + const serviceCloudComputingProviders: AllProviderTypes[] = + await taskFor(this.getExternalProviders).perform(activeFilterObject.modelName); + activeFilterObject.list = A(serviceCloudComputingProviders.sort(this.providerSorter)); + } + + providerSorter(a: AllProviderTypes, b: AllProviderTypes) { + return a.name.localeCompare(b.name); + } + + @task + @waitFor + async getExternalProviders(providerType: string) { + const serviceProviderModels: AllProviderTypes[] = (await this.store.findAll(providerType)).toArray(); + return serviceProviderModels; + } +} diff --git a/lib/osf-components/addon/components/addons-service/user-addons-manager/template.hbs b/lib/osf-components/addon/components/addons-service/user-addons-manager/template.hbs new file mode 100644 index 00000000000..ee973fc6fea --- /dev/null +++ b/lib/osf-components/addon/components/addons-service/user-addons-manager/template.hbs @@ -0,0 +1,6 @@ +{{yield (hash + user=this.user + authorizedStorageAccounts=this.authorizedStorageAccounts + filteredAddonProviders=this.filteredAddonProviders + currentListIsLoading=this.currentListIsLoading +)}} diff --git a/lib/osf-components/app/components/addons-service/user-addons-manager/component.js b/lib/osf-components/app/components/addons-service/user-addons-manager/component.js new file mode 100644 index 00000000000..316330463f0 --- /dev/null +++ b/lib/osf-components/app/components/addons-service/user-addons-manager/component.js @@ -0,0 +1 @@ +export { default } from 'osf-components/components/addons-service/user-addons-manager/component'; diff --git a/lib/osf-components/app/components/addons-service/user-addons-manager/template.js b/lib/osf-components/app/components/addons-service/user-addons-manager/template.js new file mode 100644 index 00000000000..fc10cf5159f --- /dev/null +++ b/lib/osf-components/app/components/addons-service/user-addons-manager/template.js @@ -0,0 +1 @@ +export { default } from 'osf-components/components/addons-service/user-addons-manager/template';