Skip to content
This repository was archived by the owner on Apr 14, 2026. It is now read-only.

Commit e66e06a

Browse files
committed
another batch of updates
1 parent dc87ed3 commit e66e06a

9 files changed

Lines changed: 104 additions & 35 deletions

File tree

app/guid-node/addons/index/template.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@
277277
<AddonsService::ConfiguredAddonEdit
278278
@configuredAddon={{manager.selectedConfiguration}}
279279
@authorizedAccount={{manager.selectedAccount}}
280+
@supportedResourceTypes={{manager.selectedProvider.provider.supportedResourceTypes}}
280281
@onSave={{perform manager.saveOrCreateConfiguration}}
281282
@onCancel={{manager.cancelSetup}}
282283
/>

app/models/configured-addon.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import { task } from 'ember-concurrency';
55
import UserReferenceModel from 'ember-osf-web/models/user-reference';
66
import { tracked } from 'tracked-built-ins';
77
import { taskFor } from 'ember-concurrency-ts';
8+
import { SupportedResourceTypes } from 'ember-osf-web/models/external-link-service';
89
import { ConnectedStorageOperationNames, OperationKwargs } from './addon-operation-invocation';
910
import { ConnectedCapabilities } from './authorized-account';
1011

1112

1213
export interface ConfiguredAddonEditableAttrs {
1314
displayName: string;
1415
rootFolder: string;
16+
targetId: string;
17+
resourceType: SupportedResourceTypes;
1518
}
1619

1720
export default class ConfiguredAddonModel extends Model {

app/models/configured-link-addon.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import { AsyncBelongsTo, attr, belongsTo } from '@ember-data/model';
22
import { waitFor } from '@ember/test-waiters';
33
import { task } from 'ember-concurrency';
4-
import { ConnectedLinkOperationNames, OperationKwargs } from 'ember-osf-web/models/addon-operation-invocation';
4+
import { ConnectedLinkOperationNames, Item, OperationKwargs } from 'ember-osf-web/models/addon-operation-invocation';
55
import ResourceReferenceModel from 'ember-osf-web/models/resource-reference';
66

7-
import ExternalLinkServiceModel from 'ember-osf-web/models/external-link-service';
7+
import ExternalLinkServiceModel, { SupportedResourceTypes } from 'ember-osf-web/models/external-link-service';
88
import AuthorizedLinkAccountModel from 'ember-osf-web/models/authorized-link-account';
9+
import { tracked } from 'tracked-built-ins';
10+
import { taskFor } from 'ember-concurrency-ts';
911
import ConfiguredAddonModel from './configured-addon';
1012

1113

1214
export default class ConfiguredLinkAddonModel extends ConfiguredAddonModel {
13-
@attr('number') concurrentUploads!: number;
15+
@attr('string') targetId!: string;
16+
@attr('string') resourceType!: SupportedResourceTypes;
1417

1518
@belongsTo('external-link-service', { inverse: null })
1619
externalLinkService!: AsyncBelongsTo<ExternalLinkServiceModel> & ExternalLinkServiceModel;
@@ -49,6 +52,15 @@ export default class ConfiguredLinkAddonModel extends ConfiguredAddonModel {
4952
});
5053
return await newInvocation.save();
5154
}
55+
56+
@tracked targetItemName = '';
57+
58+
@task
59+
@waitFor
60+
async getTargetItemName(this: ConfiguredLinkAddonModel) {
61+
const response = await taskFor(this.getItemInfo).perform(this.targetId);
62+
this.targetItemName = (response.operationResult as Item).itemName;
63+
}
5264
}
5365

5466
declare module 'ember-data/types/registries/model' {

lib/osf-components/addon/components/addons-service/configured-addon-edit/component.ts

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import { Item, ItemType } from 'ember-osf-web/models/addon-operation-invocation'
77
import AuthorizedAccountModel from 'ember-osf-web/models/authorized-account';
88
import AuthorizedCitationAccountModel from 'ember-osf-web/models/authorized-citation-account';
99
import AuthorizedComputingAccountModel from 'ember-osf-web/models/authorized-computing-account';
10+
import AuthorizedLinkAccountModel from 'ember-osf-web/models/authorized-link-account';
1011
import AuthorizedStorageAccountModel from 'ember-osf-web/models/authorized-storage-account';
1112
import ConfiguredAddonModel from 'ember-osf-web/models/configured-addon';
1213
import ConfiguredCitationAddonModel from 'ember-osf-web/models/configured-citation-addon';
1314
import ConfiguredComputingAddonModel from 'ember-osf-web/models/configured-computing-addon';
15+
import ConfiguredLinkAddonModel from 'ember-osf-web/models/configured-link-addon';
1416
import ConfiguredStorageAddonModel from 'ember-osf-web/models/configured-storage-addon';
1517

1618

@@ -25,9 +27,15 @@ export default class ConfiguredAddonEdit extends Component<Args> {
2527
@tracked selectedFolder = this.args.configuredAddon?.rootFolder;
2628
@tracked selectedFolderDisplayName = this.args.configuredAddon?.rootFolderName;
2729
@tracked currentItems: Item[] = [];
30+
@tracked selectedItem = (this.args.configuredAddon as ConfiguredLinkAddonModel).targetId;
31+
@tracked selectedItemDisplayName = (this.args.configuredAddon as ConfiguredLinkAddonModel).targetItemName;
32+
@tracked selectedResourceType = (this.args.configuredAddon as ConfiguredLinkAddonModel).resourceType;
2833

2934
originalName = this.displayName;
3035
originalRootFolder = this.selectedFolder;
36+
originalSelectedItem = this.selectedItem;
37+
originalResourceType = this.selectedResourceType;
38+
3139
defaultKwargs: any = {};
3240

3341
constructor(owner: unknown, args: Args) {
@@ -39,6 +47,9 @@ export default class ConfiguredAddonEdit extends Component<Args> {
3947
if (this.args.configuredAddon instanceof ConfiguredCitationAddonModel) {
4048
this.defaultKwargs['filterItems'] = ItemType.Collection;
4149
}
50+
if (this.args.configuredAddon instanceof ConfiguredLinkAddonModel) {
51+
// noop
52+
}
4253
}
4354
if (this.args.authorizedAccount) {
4455
if (this.args.authorizedAccount instanceof AuthorizedStorageAccountModel) {
@@ -47,10 +58,17 @@ export default class ConfiguredAddonEdit extends Component<Args> {
4758
if (this.args.authorizedAccount instanceof AuthorizedCitationAccountModel) {
4859
this.defaultKwargs['filterItems'] = ItemType.Collection;
4960
}
61+
if (this.args.authorizedAccount instanceof AuthorizedLinkAccountModel) {
62+
// noop
63+
}
5064
}
5165
}
5266

53-
get requiresRootFolder() {
67+
get isLinkAddon() {
68+
return this.args.configuredAddon instanceof ConfiguredLinkAddonModel;
69+
}
70+
71+
get requiresFilesWidget() {
5472
return !(
5573
this.args.authorizedAccount instanceof AuthorizedComputingAccountModel
5674
||
@@ -64,33 +82,40 @@ export default class ConfiguredAddonEdit extends Component<Args> {
6482

6583
get disableSave() {
6684
const displayNameUnchanged = this.displayName === this.originalName;
67-
const rootFolderUnchanged = this.requiresRootFolder && this.selectedFolder === this.originalRootFolder;
68-
const needsRootFolder = this.requiresRootFolder && !this.selectedFolder;
85+
const rootFolderUnchanged = this.requiresFilesWidget && !this.isLinkAddon
86+
&& this.selectedFolder === this.originalRootFolder;
87+
const targetIdUnchanged = this.isLinkAddon && this.originalSelectedItem === this.selectedItem;
88+
const resourceTypeUnchanged = this.originalResourceType === this.selectedResourceType;
89+
const needsResourceType = this.isLinkAddon && !this.selectedResourceType;
90+
const needsTargetId = this.isLinkAddon && !this.selectedItem;
91+
const needsRootFolder = this.requiresFilesWidget && !this.isLinkAddon && !this.selectedFolder;
6992

70-
if (this.invalidDisplayName || needsRootFolder) {
93+
if (this.invalidDisplayName || needsRootFolder || needsResourceType || needsTargetId) {
7194
return true;
7295
}
96+
if (this.isLinkAddon) {
97+
return targetIdUnchanged && resourceTypeUnchanged || this.args.onSave.isRunning;
98+
}
7399
return (rootFolderUnchanged && displayNameUnchanged) || this.args.onSave.isRunning;
74100
}
75101

76-
get nameValid() {
77-
return !this.invalidDisplayName && this.displayName !== this.originalName;
78-
}
79-
80-
get folderValid() {
81-
return !this.requiresRootFolder && this.selectedFolder && this.selectedFolder !== this.originalRootFolder;
82-
}
83-
84102
get onSaveArgs() {
85103
return {
86104
displayName: this.displayName,
87105
rootFolder: this.selectedFolder,
106+
targetId: this.selectedItem,
107+
resourceType: this.selectedResourceType,
88108
};
89109
}
90110

91111
@action
92-
selectFolder(folder: Item) {
93-
this.selectedFolder = folder.itemId;
94-
this.selectedFolderDisplayName = folder.itemName;
112+
selectItem(item: Item) {
113+
if (this.isLinkAddon) {
114+
this.selectedItem = item.itemId;
115+
this.selectedItemDisplayName = item.itemName;
116+
} else {
117+
this.selectedFolder = item.itemId;
118+
this.selectedFolderDisplayName = item.itemName;
119+
}
95120
}
96121
}

lib/osf-components/addon/components/addons-service/configured-addon-edit/template.hbs

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,20 @@
2121
</span>
2222
{{/if}}
2323
</div>
24-
{{#if this.requiresRootFolder }}
24+
{{#if this.requiresFilesWidget }}
2525
<div local-class='input-wrapper'>
2626
<b>
27-
{{t 'addons.configure.selected-folder'}}
27+
{{#if this.isLinkAddon}}
28+
{{t 'addons.configure.linked-item'}}
29+
{{else}}
30+
{{t 'addons.configure.selected-folder'}}
31+
{{/if}}
2832
</b>
2933
<span>
3034
{{#if this.selectedFolderDisplayName}}
3135
{{this.selectedFolderDisplayName}}
36+
{{else if this.selectedItemDisplayName}}
37+
{{this.selectedItemDisplayName}}
3238
{{else}}
3339
{{t 'addons.configure.no-folder-selected'}}
3440
{{/if}}
@@ -81,48 +87,48 @@
8187
<td colspan='2'>{{t 'addons.configure.error-loading-items'}}</td>
8288
</tr>
8389
{{else}}
84-
{{#each fileManager.currentItems as |folder|}}
90+
{{#each fileManager.currentItems as |item|}}
8591
<tr>
8692
<td>
87-
{{#if folder.mayContainRootCandidates}}
93+
{{#if (or item.mayContainRootCandidates fileManager.isLinkAddon)}}
8894
<Button
89-
data-test-folder-link='{{folder.itemName}}'
95+
data-test-folder-link='{{item.itemName}}'
9096
data-analytics-name='Go to folder'
9197
@layout='fake-link'
92-
aria-label={{t 'addons.configure.go-to-folder' folderName=folder.itemName}}
93-
{{on 'click' (fn fileManager.goToFolder folder)}}
98+
aria-label={{t 'addons.configure.go-to-folder' folderName=item.itemName}}
99+
{{on 'click' (fn fileManager.goToFolder item)}}
94100
>
95101
<span local-class='item-name'>
96-
{{#if (or (eq folder.itemType 'FOLDER') (eq folder.itemType 'COLLECTION'))}}
102+
{{#if (or (eq item.itemType 'FOLDER') (eq item.itemType 'COLLECTION'))}}
97103
<FaIcon @icon='folder' />
98104
{{else}}
99105
<FaIcon @icon='file' />
100106
{{/if}}
101-
{{folder.itemName}}
107+
{{item.itemName}}
102108
</span>
103109
</Button>
104110
{{else}}
105111
<span local-class='item-name'>
106-
{{#if (or (eq folder.itemType 'FOLDER') (eq folder.itemType 'COLLECTION'))}}
112+
{{#if (or (eq item.itemType 'FOLDER') (eq item.itemType 'COLLECTION'))}}
107113
<FaIcon @icon='folder' />
108114
{{else}}
109115
<FaIcon @icon='file' />
110116
{{/if}}
111-
{{folder.itemName}}
117+
{{item.itemName}}
112118
</span>
113119
{{/if}}
114120
</td>
115121
<td>
116-
{{#if folder.canBeRoot}}
122+
{{#if (or item.canBeRoot fileManager.isLinkAddon)}}
117123
<input
118-
data-test-root-folder-option='{{folder.itemName}}'
124+
data-test-root-folder-option='{{item.itemName}}'
119125
data-analytics-name='Select folder'
120126
type='radio'
121127
name='folder'
122-
value={{folder.itemName}}
123-
checked={{eq folder.itemId this.selectedFolder}}
124-
aria-label={{t 'addons.configure.select-folder' folderName=folder.itemName}}
125-
{{on 'change'(fn this.selectFolder folder)}}
128+
value={{item.itemName}}
129+
checked={{eq item.itemId this.selectedFolder}}
130+
aria-label={{t 'addons.configure.select-folder' folderName=item.itemName}}
131+
{{on 'change'(fn this.selectItem item)}}
126132
>
127133
{{/if}}
128134
</td>
@@ -151,6 +157,16 @@
151157
</table>
152158
</AddonsService::FileManager>
153159
{{/if}}
160+
{{#if this.isLinkAddon}}
161+
<PowerSelect
162+
@options={{@supportedResourceTypes}}
163+
@selected={{this.selectedResourceType}}
164+
@onChange={{action (mut this.selectedResourceType)}}
165+
as |resourceType|
166+
>
167+
{{resourceType}}
168+
</PowerSelect>
169+
{{/if}}
154170
<div local-class='footer-buttons-wrapper'>
155171
<Button
156172
data-test-root-folder-save

lib/osf-components/addon/components/addons-service/file-manager/component.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { Item, ListItemsResult, OperationKwargs } from 'ember-osf-web/models/add
1313
import AuthorizedAccountModel from 'ember-osf-web/models/authorized-account';
1414
import ConfiguredAddonModel from 'ember-osf-web/models/configured-addon';
1515
import captureException, { getApiErrorMessage } from 'ember-osf-web/utils/capture-exception';
16+
import ConfiguredLinkAddonModel from 'ember-osf-web/models/configured-link-addon';
1617

1718
interface Args {
1819
configuredAddon?: ConfiguredAddonModel;
@@ -46,6 +47,10 @@ export default class FileManager extends Component<Args> {
4647
taskFor(this.getStartingFolder).lastPerformed?.error;
4748
}
4849

50+
get isLinkAddon() {
51+
return this.operationInvocableModel instanceof ConfiguredLinkAddonModel;
52+
}
53+
4954
constructor(owner: unknown, args: Args) {
5055
super(owner, args);
5156
assert('Must provide a configuredAddon or authorizedAccount', args.configuredAddon || args.authorizedAccount);

lib/osf-components/addon/components/addons-service/file-manager/template.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@
1010

1111
isLoading=this.isLoading
1212
isError=this.isError
13+
isLinkAddon=this.isLinkAddon
1314
)}}

lib/osf-components/addon/components/addons-service/manager/component.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { AccountCreationArgs} from 'ember-osf-web/models/authorized-account';
2323
import AuthorizedStorageAccountModel from 'ember-osf-web/models/authorized-storage-account';
2424
import ConfiguredCitationAddonModel from 'ember-osf-web/models/configured-citation-addon';
2525
import UserReferenceModel from 'ember-osf-web/models/user-reference';
26+
import ConfiguredLinkAddonModel from 'ember-osf-web/models/configured-link-addon';
2627

2728
interface FilterSpecificObject {
2829
modelName: string;
@@ -309,6 +310,10 @@ export default class AddonsServiceManagerComponent extends Component<Args> {
309310
this.toast.success(this.intl.t('addons.configure.success', {
310311
configurationName: this.selectedConfiguration.displayName,
311312
}));
313+
} else if (this.selectedConfiguration && this.selectedConfiguration instanceof ConfiguredLinkAddonModel) {
314+
this.selectedConfiguration.targetId = args.targetId;
315+
this.selectedConfiguration.resourceType = args.resourceType;
316+
await this.selectedConfiguration.save();
312317
}
313318
this.cancelSetup();
314319
} catch(e) {

translations/en-us.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ addons:
362362
heading: 'Configure {providerName}'
363363
display-name: 'Display name'
364364
selected-folder: 'Selected folder:'
365+
linked-item: 'Linked item:'
365366
no-folder-selected: 'No folder selected'
366367
go-to-root: 'Go to home folder'
367368
go-to-folder: 'Go to folder {folderName}'

0 commit comments

Comments
 (0)