Skip to content

Commit e2621aa

Browse files
authored
[ENG-3886] Hide node-files page links based on permission (#1572)
- Ticket: [ENG-3886] - Feature flag: n/a ## Purpose - Hide `Contributors` and `Settings` link for non-contributors ## Summary of Changes - Add condition to show/hide Contributors and Settings links - Remove logic around Analytics link (doesn't match legacy page)
1 parent e93ea45 commit e2621aa

File tree

5 files changed

+68
-27
lines changed

5 files changed

+68
-27
lines changed

app/guid-node/files/provider/controller.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ import Controller from '@ember/controller';
22
import { inject as service } from '@ember/service';
33
import Media from 'ember-responsive';
44

5+
import CurrentUser from 'ember-osf-web/services/current-user';
6+
57
export default class GuidNodeFilesProvider extends Controller {
68
@service media!: Media;
9+
@service currentUser!: CurrentUser;
710

811
get isDesktop() {
912
return this.media.isDesktop;

app/guid-node/files/provider/route.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@ import Intl from 'ember-intl/services/intl';
88
import Toast from 'ember-toastr/services/toast';
99
import FileProviderModel from 'ember-osf-web/models/file-provider';
1010
import NodeModel from 'ember-osf-web/models/node';
11-
import { Permission } from 'ember-osf-web/models/osf-model';
1211
import { GuidRouteModel } from 'ember-osf-web/resolve-guid/guid-route';
13-
import CurrentUser from 'ember-osf-web/services/current-user';
1412
import captureException, { getApiErrorMessage } from 'ember-osf-web/utils/capture-exception';
1513

1614
export default class GuidNodeFilesProviderRoute extends Route.extend({}) {
17-
@service currentUser!: CurrentUser;
1815
@service intl!: Intl;
1916
@service toast!: Toast;
2017

@@ -30,9 +27,7 @@ export default class GuidNodeFilesProviderRoute extends Route.extend({}) {
3027
},
3128
);
3229
const provider = fileProviders.findBy('id', fileProviderId) as FileProviderModel;
33-
const hasWritePermission = node.currentUserPermissions.includes(Permission.Write);
34-
const isViewOnly = Boolean(this.currentUser.viewOnlyToken);
35-
return {provider, fileProviders, node, hasWritePermission, isViewOnly};
30+
return {provider, fileProviders, node};
3631
} catch (e) {
3732
const errorMessage = this.intl.t(
3833
'osf-components.file-browser.errors.load_file_providers',

app/guid-node/files/provider/template.hbs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
@label={{t 'node.left_nav.wiki'}}
8282
/>
8383
{{/if}}
84-
{{#unless this.model.providerTask.value.isViewOnly}}
84+
{{#if (or this.model.providerTask.value.node.public this.model.providerTask.value.node.userHasReadPermission)}}
8585
<leftNav.link
8686
data-test-analytics-link
8787
data-analytics-name='Analytics'
@@ -90,7 +90,7 @@
9090
@icon='chart-bar'
9191
@label={{t 'node.left_nav.analytics'}}
9292
/>
93-
{{/unless}}
93+
{{/if}}
9494
{{#unless this.model.providerTask.value.node.isAnonymous}}
9595
<leftNav.link
9696
data-test-registrations-link
@@ -101,15 +101,17 @@
101101
@label={{t 'node.left_nav.registrations'}}
102102
/>
103103
{{/unless}}
104-
{{#unless this.model.providerTask.value.isViewOnly}}
105-
<leftNav.link
106-
data-test-contributors-link
107-
data-analytics-name='Contributors'
108-
@href='/{{this.model.node.guid}}/contributors/'
109-
@icon='users'
110-
@label={{t 'node.left_nav.contributors'}}
111-
/>
112-
{{#if this.model.providerTask.value.hasWritePermission}}
104+
{{#unless this.currentUser.viewOnlyToken}}
105+
{{#if this.model.providerTask.value.node.userHasReadPermission}}
106+
<leftNav.link
107+
data-test-contributors-link
108+
data-analytics-name='Contributors'
109+
@href='/{{this.model.node.guid}}/contributors/'
110+
@icon='users'
111+
@label={{t 'node.left_nav.contributors'}}
112+
/>
113+
{{/if}}
114+
{{#if this.model.providerTask.value.node.userHasWritePermission}}
113115
<leftNav.link
114116
data-test-addons-link
115117
data-analytics-name='Add-ons'
@@ -118,13 +120,15 @@
118120
@label={{t 'node.left_nav.add-ons'}}
119121
/>
120122
{{/if}}
121-
<leftNav.link
122-
data-test-settings-link
123-
data-analytics-name='Settings'
124-
@href='/{{this.model.node.guid}}/settings/'
125-
@icon='cogs'
126-
@label={{t 'node.left_nav.settings'}}
127-
/>
123+
{{#if this.this.model.providerTask.value.node.userHasReadPermission}}
124+
<leftNav.link
125+
data-test-settings-link
126+
data-analytics-name='Settings'
127+
@href='/{{this.model.node.guid}}/settings/'
128+
@icon='cogs'
129+
@label={{t 'node.left_nav.settings'}}
130+
/>
131+
{{/if}}
128132
{{/unless}}
129133
</layout.leftNavOld>
130134
<layout.main local-class='OverviewBody'>
@@ -134,13 +138,13 @@
134138
{{#let (get mapper this.model.providerName) as |ProviderManager|}}
135139
<ProviderManager
136140
@provider={{this.model.providerTask.value.provider}}
137-
@isViewOnly={{this.model.providerTask.value.isViewOnly}}
141+
@isViewOnly={{this.model.providerTask.value.currentUser.viewOnlyToken}}
138142
as |manager|
139143
>
140144
<div local-class='FileBrowser'>
141145
<FileBrowser
142146
@manager={{manager}}
143-
@selectable={{not this.model.providerTask.value.isViewOnly}}
147+
@selectable={{not this.model.providerTask.value.currentUser.viewOnlyToken}}
144148
@enableUpload={{true}}
145149
/>
146150
</div>

app/models/node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export default class NodeModel extends AbstractNodeModel.extend(Validations, Col
8787
@attr('fixstring') title!: string;
8888
@attr('fixstring') description!: string;
8989
@attr('node-category') category!: NodeCategory;
90-
@attr('boolean') currentUserIsContributor!: boolean;
90+
@attr('boolean') currentUserIsContributor!: boolean;
9191
@attr('boolean') fork!: boolean;
9292
@alias('fork') isFork!: boolean;
9393
@attr('boolean') collection!: boolean;

tests/acceptance/guid-node/files-test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { click, setupOSFApplicationTest, visit } from 'ember-osf-web/tests/helpe
1010
import NodeModel from 'ember-osf-web/models/node';
1111
import FileModel from 'ember-osf-web/models/file';
1212
import FileProviderModel from 'ember-osf-web/models/file-provider';
13+
import { Permission } from 'ember-osf-web/models/osf-model';
1314

1415
interface GuidNodeTestContext extends TestContext {
1516
node: ModelInstance<NodeModel>;
@@ -31,7 +32,45 @@ module('Acceptance | guid-node/files', hooks => {
3132
});
3233
});
3334

35+
test('left-nav: logged out', async function(this: GuidNodeTestContext, assert) {
36+
await visit(`/${this.node.id}/files`);
37+
assert.equal(currentRouteName(), 'guid-node.files.provider', 'logged out: Current route is files');
38+
assert.dom('[data-test-overview-link]').exists('logged out: Overview link exists');
39+
assert.dom('[data-test-files-link]').exists('logged out: Files link exists');
40+
assert.dom('[data-test-analytics-link]').exists('logged out: Analytics link exists');
41+
assert.dom('[data-test-registrations-link]').exists('logged out: Registrations link exists');
42+
assert.dom('[data-test-contributors-link]').doesNotExist('logged out: Contributors link does not exist');
43+
assert.dom('[data-test-settings-link]').doesNotExist('logged out: Settings link does not exist');
44+
});
45+
46+
test('left-nav: VOL', async function(this: GuidNodeTestContext, assert) {
47+
const currentUser = this.owner.lookup('service:current-user');
48+
currentUser.viewOnlyToken = 'SomeVolToken';
49+
await visit(`/${this.node.id}/files`);
50+
assert.equal(currentRouteName(), 'guid-node.files.provider', 'VOL: Current route is files');
51+
assert.dom('[data-test-overview-link]').exists('VOL: Overview link exists');
52+
assert.dom('[data-test-files-link]').exists('VOL: Files link exists');
53+
assert.dom('[data-test-analytics-link]').exists('VOL: Analytics link exists');
54+
assert.dom('[data-test-registrations-link]').exists('VOL: Registrations link exists');
55+
assert.dom('[data-test-contributors-link]').doesNotExist('VOL: Contributors link does not exist');
56+
assert.dom('[data-test-settings-link]').doesNotExist('VOL: Settings link does not exist');
57+
});
58+
59+
test('left-nav: AVOL', async function(this: GuidNodeTestContext, assert) {
60+
const node = await this.owner.lookup('service:store').findRecord('node', this.node.id);
61+
node.apiMeta = { version: '2', anonymous: true };
62+
await visit(`/${this.node.id}/files`);
63+
assert.equal(currentRouteName(), 'guid-node.files.provider', 'AVOL: Current route is files');
64+
assert.dom('[data-test-overview-link]').exists('AVOL: Overview link exists');
65+
assert.dom('[data-test-files-link]').exists('AVOL: Files link exists');
66+
assert.dom('[data-test-analytics-link]').exists('AVOL: Analytics link exists');
67+
assert.dom('[data-test-registrations-link]').doesNotExist('AVOL: Registrations link does not exist');
68+
assert.dom('[data-test-contributors-link]').doesNotExist('AVOL: Contributors link does not exist');
69+
assert.dom('[data-test-settings-link]').doesNotExist('AVOL: Settings link does not exist');
70+
});
71+
3472
test('read user', async function(this: GuidNodeTestContext, assert) {
73+
this.node.currentUserPermissions = [Permission.Read];
3574
await visit(`/${this.node.id}/files`);
3675

3776
assert.equal(currentRouteName(), 'guid-node.files.provider', 'Current route is files');

0 commit comments

Comments
 (0)