Skip to content

Commit

Permalink
Fetch starting folder info for file-manager
Browse files Browse the repository at this point in the history
  • Loading branch information
futa-ikeda committed Jun 21, 2024
1 parent cfd8a32 commit 4a662bb
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 89 deletions.
13 changes: 13 additions & 0 deletions app/models/configured-storage-addon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export enum ConnectedOperationNames {
HasRevisions = 'has_revisions',
ListRootItems = 'list_root_items',
ListChildItems = 'list_child_items',
GetItemInfo = 'get_item_info',
}

export interface OperationKwargs {
Expand Down Expand Up @@ -55,6 +56,18 @@ export default class ConfiguredStorageAddonModel extends ConfiguredAddonModel {
return await newInvocation.save();
}

@task
@waitFor
async getItemInfo(this: ConfiguredStorageAddonModel, itemId: string) {
const newInvocation = this.store.createRecord('addon-operation-invocation', {
operationName: ConnectedOperationNames.GetItemInfo,
operationKwargs: { itemId },
thruAddon: this,
byUser: await this.accountOwner,
});
return await newInvocation.save();
}

get externalServiceId() {
return (this as ConfiguredStorageAddonModel).belongsTo('externalStorageService').id();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,15 @@ export default class FileManager extends Component<Args> {

constructor(owner: unknown, args: Args) {
super(owner, args);
taskFor(this.getStartingFolder).perform();
taskFor(this.getItems).perform();
}


@action
goToRoot() {
this.cursor = '';
this.currentPath = [];
this.currentPath = this.currentPath.slice(0, 1);
this.currentFolderId = this.args.startingFolderId;
taskFor(this.getItems).perform();
}
Expand All @@ -66,6 +67,19 @@ export default class FileManager extends Component<Args> {
taskFor(this.getItems).perform();
}


@task
@waitFor
async getStartingFolder() {
const { startingFolderId, configuredStorageAddon } = this.args;
try {
const invocation = await taskFor(configuredStorageAddon.getItemInfo).perform(startingFolderId);
this.currentPath = invocation.operationResult.items;
} catch (e) {
this.toast.error(this.intl.t('osf-components.addons-service.file-manager.get-item-error'));
}
}

@task
@waitFor
async getItems() {
Expand All @@ -79,7 +93,7 @@ export default class FileManager extends Component<Args> {
this.currentItems = this.cursor ? [...this.currentItems, ...operationResult.items] : operationResult.items;
this.hasMore = Boolean(invocation.operationResult.cursor);
} catch (e) {
this.toast.error(this.intl.t('osf-components.addons-service.file-manager.error'));
this.toast.error(this.intl.t('osf-components.addons-service.file-manager.get-items-error'));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,82 +1,83 @@
<AddonsService::FileManager
data-analytics-scope='Root folder picker'
@configuredStorageAddon={{@configuredStorageAddon}}
@defaultKwargs={{this.defaultKwargs}}
@startingFolderId={{this.selectedFolder}}
as |fileManager|
>
{{#each fileManager.currentPath as |pathItem|}}
<span>
<Button
data-test-folder-path-option='{{pathItem.itemName}}'
data-analytics-name='Go to ancestor folder'
@layout='fake-link'
aria-label={{t 'addons.configure.go-to-folder' folderName=pathItem.itemName}}
{{on 'click' (fn fileManager.goToFolder pathItem)}}
>
{{pathItem.itemName}}
</Button>
</span>
{{/each}}
<table>
<thead>
<tr>
<th>{{t 'addons.configure.table-headings.folder-name'}}</th>
<th>{{t 'addons.configure.table-headings.select'}}</th>
</tr>
</thead>
<tbody>
{{#each fileManager.currentItems as |folder|}}
<div data-analytics-scope='Root folder picker'>
<AddonsService::FileManager
@configuredStorageAddon={{@configuredStorageAddon}}
@defaultKwargs={{this.defaultKwargs}}
@startingFolderId={{this.selectedFolder}}
as |fileManager|
>
{{#each fileManager.currentPath as |pathItem|}}
<span>
<Button
data-test-folder-path-option='{{pathItem.itemName}}'
data-analytics-name='Go to ancestor folder'
@layout='fake-link'
aria-label={{t 'addons.configure.go-to-folder' folderName=pathItem.itemName}}
{{on 'click' (fn fileManager.goToFolder pathItem)}}
>
{{pathItem.itemName}}
</Button>
</span>
{{/each}}
<table>
<thead>
<tr>
<td>
<Button
data-test-folder-link='{{folder.itemName}}'
data-analytics-name='Go to folder'
@layout='fake-link'
aria-label={{t 'addons.configure.go-to-folder' folderName=folder.itemName}}
{{on 'click' (fn fileManager.goToFolder folder)}}
>
<FaIcon @icon='folder' />
{{folder.itemName}}
</Button>
</td>
<td>
<input
data-test-root-folder-option='{{folder.itemName}}'
data-analytics-name='Select folder'
type='radio'
name='folder'
value={{folder.itemName}}
aria-label={{t 'addons.configure.select-folder' folderName=folder.itemName}}
{{on 'change'(fn this.selectFolder folder)}}
>
</td>
<th>{{t 'addons.configure.table-headings.folder-name'}}</th>
<th>{{t 'addons.configure.table-headings.select'}}</th>
</tr>
{{else}}
<tr>
<td colspan='2'>{{t 'addons.configure.no-folders'}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{#if fileManager.isLoading}}
<LoadingIndicator @dark={{true}} />
{{/if}}
</AddonsService::FileManager>
<Button
data-test-root-folder-save
data-analytics-name='Save selected folder'
@type='primary'
disabled={{this.disableSave}}
{{on 'click' (fn @onSave this.selectedFolder)}}
>
{{t 'general.save'}}
</Button>
<Button
data-test-root-folder-cancel
data-analytics-name='Cancel'
@type='secondary'
{{on 'click' @onCancel}}
>
{{t 'general.cancel'}}
</Button>
</thead>
<tbody>
{{#each fileManager.currentItems as |folder|}}
<tr>
<td>
<Button
data-test-folder-link='{{folder.itemName}}'
data-analytics-name='Go to folder'
@layout='fake-link'
aria-label={{t 'addons.configure.go-to-folder' folderName=folder.itemName}}
{{on 'click' (fn fileManager.goToFolder folder)}}
>
<FaIcon @icon='folder' />
{{folder.itemName}}
</Button>
</td>
<td>
<input
data-test-root-folder-option='{{folder.itemName}}'
data-analytics-name='Select folder'
type='radio'
name='folder'
value={{folder.itemName}}
aria-label={{t 'addons.configure.select-folder' folderName=folder.itemName}}
{{on 'change'(fn this.selectFolder folder)}}
>
</td>
</tr>
{{else}}
<tr>
<td colspan='2'>{{t 'addons.configure.no-folders'}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{#if fileManager.isLoading}}
<LoadingIndicator @dark={{true}} />
{{/if}}
<Button
data-test-root-folder-save
data-analytics-name='Save selected folder'
@type='primary'
disabled={{this.disableSave}}
{{on 'click' (fn @onSave this.selectedFolder)}}
>
{{t 'general.save'}}
</Button>
<Button
data-test-root-folder-cancel
data-analytics-name='Cancel'
@type='secondary'
{{on 'click' @onCancel}}
>
{{t 'general.cancel'}}
</Button>
</AddonsService::FileManager>
</div>
25 changes: 18 additions & 7 deletions mirage/views/addons.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { HandlerContext, ModelInstance, NormalizedRequestAttrs, Request, Response, Schema } from 'ember-cli-mirage';
import { timeout } from 'ember-concurrency';

import { InvocationStatus } from 'ember-osf-web/models/addon-operation-invocation';
import { InvocationStatus, Item, ItemType } from 'ember-osf-web/models/addon-operation-invocation';
import AuthorizedCitationAccountModel from 'ember-osf-web/models/authorized-citation-account';
import AuthorizedComputingAccountModel from 'ember-osf-web/models/authorized-computing-account';
import { AddonCredentialFields} from 'ember-osf-web/models/authorized-account';
import AuthorizedStorageAccountModel from 'ember-osf-web/models/authorized-storage-account';
import { ConnectedOperationNames } from 'ember-osf-web/models/configured-storage-addon';
import { CredentialsFormat } from 'ember-osf-web/models/external-service';
import ExternalStorageServiceModel from 'ember-osf-web/models/external-storage-service';
import ExternalCitationServiceModel from 'ember-osf-web/models/external-citation-service';
Expand Down Expand Up @@ -257,13 +258,23 @@ export function createAddonOperationInvocation(this: HandlerContext, schema: Sch
) as NormalizedRequestAttrs<MirageAddonOperationInvocation>;
const kwargs = attrs.operationKwargs;
const invocation = schema.addonOperationInvocations.create(attrs) as ModelInstance<MirageAddonOperationInvocation>;
let items: Item[] = [];
const folderId = kwargs.itemId || 'root';
const items = '12345'.split('').map(i => ({
itemId: `${folderId}-${i}`,
itemName: `${kwargs.itemType}${i} in ${folderId}`,
itemType: kwargs.itemType,
itemPath: folderId,
}));
if (attrs.operationName === ConnectedOperationNames.GetItemInfo) {
items = [{
itemId: folderId,
itemName: `Item with ID ${folderId}`,
itemType: kwargs.itemType || ItemType.Folder,
itemPath: folderId,
}];
} else {
items = '12345'.split('').map(i => ({
itemId: `${folderId}-${i}`,
itemName: `${kwargs.itemType}${i} in ${folderId}`,
itemType: kwargs.itemType,
itemPath: folderId,
}));
}
invocation.update({
invocationStatus: InvocationStatus.SUCCESS,
created: new Date(),
Expand Down
4 changes: 4 additions & 0 deletions translations/en-us.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2171,6 +2171,10 @@ routes:
institution: Institution
email: Email
osf-components:
addons-srvice:
file-manager:
get-item-error: 'Error fetching item'
get-items-error: 'Error fetching items'
addon-card:
connect: Connect
configure: Configure
Expand Down

0 comments on commit 4a662bb

Please sign in to comment.