Skip to content

Commit

Permalink
Merge branch 'release/23.14.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
adlius committed Nov 10, 2023
2 parents 6814ce3 + 45a9766 commit 56e8128
Show file tree
Hide file tree
Showing 20 changed files with 330 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [23.14.0] - 2023-11-10
### Added
- BOA addon

## [23.13.0] - 2023-10-25
### Added
- Search improvement post release fixes
Expand Down Expand Up @@ -1954,6 +1958,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- Quick Files

[23.14.0]: https://github.com/CenterForOpenScience/ember-osf-web/releases/tag/23.14.0
[23.13.0]: https://github.com/CenterForOpenScience/ember-osf-web/releases/tag/23.13.0
[23.12.1]: https://github.com/CenterForOpenScience/ember-osf-web/releases/tag/23.12.1
[23.12.0]: https://github.com/CenterForOpenScience/ember-osf-web/releases/tag/23.12.0
Expand Down
1 change: 1 addition & 0 deletions app/guid-file/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export default class GuidFile extends Route {
};
this.set('headTags', this.metaTags.getHeadTags(metaTagsData));
this.headTagsService.collectHeadTags();
await taskFor(model.target.get('getEnabledAddons')).perform();
blocker.done();
}

Expand Down
7 changes: 6 additions & 1 deletion app/guid-file/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@
({{t 'general.version'}}: {{this.viewedVersion}})
{{/if}}
</h2>
<FileActionsMenu @item={{this.model}} @onDelete={{this.onDelete}} @allowRename={{false}} />
<FileActionsMenu
@item={{this.model}}
@onDelete={{this.onDelete}}
@allowRename={{false}}
@addonsEnabled={{this.model.fileModel.target.addonsEnabled}}
/>
</div>
</:header>
<:body>
Expand Down
1 change: 1 addition & 0 deletions app/guid-node/files/provider/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default class GuidNodeFilesProviderRoute extends Route.extend({}) {
@waitFor
async fileProviderTask(guidRouteModel: GuidRouteModel<NodeModel>, fileProviderId: string) {
const node = await guidRouteModel.taskInstance;
await taskFor(node.getEnabledAddons).perform();
try {
const fileProviders = await node.queryHasMany(
'files',
Expand Down
36 changes: 36 additions & 0 deletions app/models/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import { computed } from '@ember/object';
import { alias, bool, equal, not } from '@ember/object/computed';
import { inject as service } from '@ember/service';
import { htmlSafe } from '@ember/template';
import { tracked } from '@glimmer/tracking';
import { buildValidations, validator } from 'ember-cp-validations';
import Intl from 'ember-intl/services/intl';

import config from 'ember-osf-web/config/environment';
import { task } from 'ember-concurrency';
import { waitFor } from '@ember/test-waiters';

import getRelatedHref from 'ember-osf-web/utils/get-related-href';

import AbstractNodeModel from 'ember-osf-web/models/abstract-node';
Expand All @@ -25,6 +30,13 @@ import RegistrationModel from './registration';
import SubjectModel from './subject';
import WikiModel from './wiki';

const {
OSF: {
apiUrl,
apiNamespace,
},
} = config;

const Validations = buildValidations({
title: [
validator('presence', true),
Expand Down Expand Up @@ -108,6 +120,10 @@ export default class NodeModel extends AbstractNodeModel.extend(Validations, Col
@attr('boolean') currentUserCanComment!: boolean;
@attr('boolean') wikiEnabled!: boolean;

// FE-only property to check enabled addons.
// null until getEnabledAddons has been called
@tracked addonsEnabled?: string[];

@hasMany('contributor', { inverse: 'node' })
contributors!: AsyncHasMany<ContributorModel> & ContributorModel[];

Expand Down Expand Up @@ -311,6 +327,26 @@ export default class NodeModel extends AbstractNodeModel.extend(Validations, Col

this.set('nodeLicense', props);
}

@task
@waitFor
async getEnabledAddons() {
const endpoint = `${apiUrl}/${apiNamespace}/nodes/${this.id}/addons/`;
const response = await this.currentUser.authenticatedAJAX({
url: endpoint,
type: 'GET',
headers: {
'Content-Type': 'application/json',
},
xhrFields: { withCredentials: true },
});
if (response.data) {
const addonList = response.data
.filter((addon: any) => addon.attributes.node_has_auth)
.map((addon: any) => addon.id);
this.set('addonsEnabled', addonList);
}
}
}

declare module 'ember-data/types/registries/model' {
Expand Down
8 changes: 8 additions & 0 deletions app/packages/files/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ export default abstract class File {
);
}

get isBoaFile() {
return this.fileModel.name.endsWith('.boa');
}

get providerIsOsfstorage() {
return this.fileModel.provider === 'osfstorage';
}

async createFolder(newFolderName: string) {
if (this.fileModel.isFolder) {
await this.fileModel.createFolder(newFolderName);
Expand Down
33 changes: 33 additions & 0 deletions lib/osf-components/addon/components/file-actions-menu/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { inject as service } from '@ember/service';
import Media from 'ember-responsive';
import File from 'ember-osf-web/packages/files/file';
import StorageManager from 'osf-components/components/storage-provider-manager/storage-manager/component';
import NodeModel from 'ember-osf-web/models/node';

interface Args {
item: File;
onDelete: () => void;
manager?: StorageManager; // No manager for file-detail page
addonsEnabled? : string[];
}

export default class FileActionsMenu extends Component<Args> {
Expand All @@ -19,6 +21,7 @@ export default class FileActionsMenu extends Component<Args> {
@tracked moveModalOpen = false;
@tracked useCopyModal = false;
@tracked renameModalOpen = false;
@tracked isSubmitToBoaModalOpen = false;

@action
closeDeleteModal() {
Expand All @@ -34,4 +37,34 @@ export default class FileActionsMenu extends Component<Args> {
openRenameModal() {
this.renameModalOpen = true;
}

@action
closeSubmitToBoaModal() {
this.isSubmitToBoaModalOpen = false;
}

@action
openSubmitToBoaModal() {
this.isSubmitToBoaModalOpen = true;
}

get isBoaEnabled() {
return this.args.addonsEnabled?.includes('boa');
}

get showSubmitToBoa() {
const { item, manager } = this.args;
if (item.providerIsOsfstorage && item.isBoaFile && this.isBoaEnabled) {
let userCanUploadToHere;
if (manager) {
userCanUploadToHere = manager.currentFolder.userCanUploadToHere;
} else {
const storage = (item.fileModel.target as unknown as NodeModel).get('storage');
const writableTarget = item.currentUserPermission === 'write' && !item.targetIsRegistration;
userCanUploadToHere = writableTarget && !storage.get('isOverStorageCap');
}
return userCanUploadToHere;
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { inject as service } from '@ember/service';
import { waitFor } from '@ember/test-waiters';
import Component from '@glimmer/component';
import { task } from 'ember-concurrency';
import IntlService from 'ember-intl/services/intl';
import File from 'ember-osf-web/packages/files/file';
import captureException, { getApiErrorMessage } from 'ember-osf-web/utils/capture-exception';
import config from 'ember-osf-web/config/environment';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';

interface Args {
file: File;
isOpen: boolean;
closeModal: () => {};
}

export default class SubmitToBoaModal extends Component<Args> {
@service toast!: Toastr;
@service intl!: IntlService;
@tracked selectedDataset?: string;

datasets = [
'2022 Jan/Java',
'2022 Feb/Python',
'2021 Method Chains',
'2021 Aug/Python',
'2021 Aug/Kotlin (small)',
'2021 Aug/Kotlin',
'2021 Jan/ML-Verse',
'2020 August/Python-DS',
'2019 October/GitHub (small)',
'2019 October/GitHub (medium)',
'2019 October/GitHub',
'2015 September/GitHub',
'2013 September/SF (small)',
'2013 September/SF (medium)',
'2013 September/SF',
'2013 May/SF',
'2013 February/SF',
'2012 July/SF',
];

@action
onDatasetChange(newDataset: string) {
this.selectedDataset = newDataset;
}

@task
@waitFor
async confirmSubmitToBoa() {
try {
const file = this.args.file;
const fileModel = file.fileModel;
const parentFolder = await fileModel.get('parentFolder');
const grandparentFolder = await parentFolder.get('parentFolder');
const endpoint = config.OSF.url + 'api/v1/project/' + fileModel.target.get('id') + '/boa/submit-job/';
const uploadLink = new URL(parentFolder.get('links').upload as string);
uploadLink.searchParams.set('kind', 'file');
const payload = {
data: {
nodeId: fileModel.target.get('id'),
name: file.name,
materialized: fileModel.materializedPath,
sizeInt: fileModel.size,
links: {
download: file.links.download,
upload: file.links.upload,
},
},
parent: {
links: {
upload: uploadLink.toString(),
},
isAddonRoot: !grandparentFolder,
},
dataset: this.selectedDataset,
};
await this.args.file.currentUser.authenticatedAJAX({
url: endpoint,
type: 'POST',
data: JSON.stringify(payload),
xhrFields: { withCredentials: true },
headers: {
'Content-Type': 'application/json',
},
});

this.args.closeModal();
} catch (e) {
captureException(e);
const errorMessageKey = this.intl.t('osf-components.file-browser.submit_to_boa_fail',
{ fileName: this.args.file.name, htmlSafe: true }) as string;
this.toast.error(getApiErrorMessage(e), errorMessageKey);
return;
}

this.toast.success(
this.intl.t('osf-components.file-browser.submit_to_boa_success', { fileName: this.args.file.name }),
);
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<OsfDialog @isOpen={{@isOpen}} @onClose={{@closeModal}} as |dialog|>
<dialog.heading>
{{t 'osf-components.file-browser.submit_to_boa'}}
</dialog.heading>
<dialog.main>

<p>{{t 'osf-components.file-browser.boa_dataset_spiel'}}</p>
<PowerSelect
@options={{this.datasets}}
@selected={{this.selectedDataset}}
@placeholder={{t 'osf-components.file-browser.boa_dataset_select_placeholder'}}
@onChange={{this.onDatasetChange}}
as |dataset|
>
{{dataset}}
</PowerSelect>
<p>{{t 'osf-components.file-browser.confirm_submit_to_boa' fileName=@file.name}}</p>

</dialog.main>
<dialog.footer>
<Button
{{on 'click' (fn (mut @isOpen) false)}}
>
{{t 'general.cancel'}}
</Button>
<Button
@type='primary'
disabled={{or this.confirmSubmitToBoa.isRunning (not this.selectedDataset)}}
{{on 'click' (perform this.confirmSubmitToBoa)}}
>
{{t 'osf-components.file-browser.confirm_submit_to_boa_yes'}}
</Button>
</dialog.footer>
</OsfDialog>
22 changes: 22 additions & 0 deletions lib/osf-components/addon/components/file-actions-menu/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,31 @@
</Button>
{{/if}}
{{/if}}
{{#if this.showSubmitToBoa}}
<Button
@layout='fake-link'
data-test-submit-to-boa
data-analytics-name='Submit to Boa'
local-class='DropdownItem'
{{on 'click' (queue
dropdown.close
this.openSubmitToBoaModal
)}}
>
<FaIcon @icon='upload' />
{{t 'file_actions_menu.submit_to_boa'}}
</Button>
{{/if}}
</dropdown.content>
</ResponsiveDropdown>
<FileActionsMenu::DeleteModal @file={{@item}} @isOpen={{this.isDeleteModalOpen}} @closeModal={{this.closeDeleteModal}} @onDelete={{@onDelete}} />
{{#if this.showSubmitToBoa}}
<FileActionsMenu::SubmitToBoaModal
@file={{@item}}
@isOpen={{this.isSubmitToBoaModalOpen}}
@closeModal={{this.closeSubmitToBoaModal}}
/>
{{/if}}
{{#if @manager}}
<MoveFileModal
@isOpen={{this.moveModalOpen}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,13 @@
local-class='FileList__item__options'
>
{{#unless @manager.selectedFiles}}
<FileActionsMenu @item={{@item}} @onDelete={{@manager.reload}} @manager={{@manager}} @allowRename={{true}} />
<FileActionsMenu
@item={{@item}}
@onDelete={{@manager.reload}}
@manager={{@manager}}
@allowRename={{true}}
@addonsEnabled={{@manager.targetNode.addonsEnabled}}
/>
{{/unless}}
</div>
</li>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'osf-components/components/file-actions-menu/submit-to-boa-modal/component';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'osf-components/components/file-actions-menu/submit-to-boa-modal/template';
Loading

0 comments on commit 56e8128

Please sign in to comment.