Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 29 additions & 25 deletions lib/osf-components/addon/components/files/item/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,47 @@
<FaIcon @icon='angle-left' @fixedWidth={{true}} />
<span local-class='filename'>{{this.item.itemName}}</span>
</div>
<span local-class='delete-button'>
<DeleteButton
data-test-delete-current-folder='{{this.item.id}}'
@buttonLabel={{t 'osf-components.files-widget.delete'}}
@delete={{fn @filesManager.deleteFileTask this.item}}
@small={{true}}
@noBackground={{true}}
@modalTitle={{t 'osf-components.files-widget.confirm_delete.title_folder' filename=this.item.itemName}}
@confirmButtonText={{t 'osf-components.files-widget.delete'}}
@shouldStopPropagation={{true}}
>
<div local-class='destroy-red'>{{t 'osf-components.files-widget.confirm_delete.body'}}</div>
</DeleteButton>
</span>
{{else}}
<div local-class='name-container'>
<FileIcon @item={{this.item}} />
<span data-test-file-name local-class='filename'>{{this.item.itemName}}</span>
</div>
{{#unless this.item.isFolder}}
<time local-class='date-modified' data-test-file-date-modified>
{{this.date}}
</time>
{{#if @filesManager.canEdit}}
<span local-class='delete-button'>
<DeleteButton
data-test-delete-file='{{this.item.id}}'
data-test-delete-current-folder='{{this.item.id}}'
@buttonLabel={{t 'osf-components.files-widget.delete'}}
@delete={{fn @filesManager.deleteFileTask this.item}}
@small={{true}}
@noBackground={{true}}
@modalTitle={{t 'osf-components.files-widget.confirm_delete.title_file' filename=this.item.itemName}}
@modalTitle={{t 'osf-components.files-widget.confirm_delete.title_folder' filename=this.item.itemName}}
@confirmButtonText={{t 'osf-components.files-widget.delete'}}
@shouldStopPropagation={{true}}
>
<div local-class='destroy-red'>{{t 'osf-components.files-widget.confirm_delete.body'}}</div>
</DeleteButton>
</span>
{{/if}}
{{else}}
<div local-class='name-container'>
<FileIcon @item={{this.item}} />
<span data-test-file-name local-class='filename'>{{this.item.itemName}}</span>
</div>
{{#unless this.item.isFolder}}
<time local-class='date-modified' data-test-file-date-modified>
{{this.date}}
</time>
{{#if @filesManager.canEdit}}
<span local-class='delete-button'>
<DeleteButton
data-test-delete-file='{{this.item.id}}'
@buttonLabel={{t 'osf-components.files-widget.delete'}}
@delete={{fn @filesManager.deleteFileTask this.item}}
@small={{true}}
@noBackground={{true}}
@modalTitle={{t 'osf-components.files-widget.confirm_delete.title_file' filename=this.item.itemName}}
@confirmButtonText={{t 'osf-components.files-widget.delete'}}
@shouldStopPropagation={{true}}
>
<div local-class='destroy-red'>{{t 'osf-components.files-widget.confirm_delete.body'}}</div>
</DeleteButton>
</span>
{{/if}}
{{/unless}}
{{/if}}
</div>
25 changes: 14 additions & 11 deletions lib/osf-components/addon/components/files/menu/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
@onClose={{fn this.onCloseMenu @isUploading}}
as |dropdownMenu|
>
<div local-class='actions-menu-trigger'>
<BsButton
local-class='trigger-button {{if dropdownMenu.isOpen 'close-button'}}'
aria-label={{t 'osf-components.files-widget.expand_files_menu'}}
data-ebd-id='{{dropdownMenu.uniqueId}}-trigger'
@type='success'
{{on 'click' dropdownMenu.toggle}}
>
<FaIcon @icon='plus' @size='2x' @fixedWidth={{true}} />
</BsButton>
</div>
{{#if this.canEdit}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if disabling the buttons in the menu or hiding the trigger is the way to go. It's a bigger concern though around how we render "unusable" UI.

<div local-class='actions-menu-trigger'>
<BsButton
data-test-files-menu-trigger
local-class='trigger-button {{if dropdownMenu.isOpen 'close-button'}}'
aria-label={{t 'osf-components.files-widget.expand_files_menu'}}
data-ebd-id='{{dropdownMenu.uniqueId}}-trigger'
@type='success'
{{on 'click' dropdownMenu.toggle}}
>
<FaIcon @icon='plus' @size='2x' @fixedWidth={{true}} />
</BsButton>
</div>
{{/if}}
<dropdownMenu.content
role='menu'
local-class='actions-menu-content'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { layout } from 'ember-osf-web/decorators/component';

import { assert } from '@ember/debug';
import DraftRegistrationModel from 'ember-osf-web/models/draft-registration';
import RevisionModel from 'ember-osf-web/models/revision';
import { PageManager } from 'ember-osf-web/packages/registration-schema/page-manager';
import styles from './styles';
import template from './template';
Expand All @@ -14,10 +15,13 @@ import template from './template';
export default class PageRenderer extends Component {
// Required param
pageManager!: PageManager;
draftRegistration!: DraftRegistrationModel;
draftRegistration?: DraftRegistrationModel;
revision?: RevisionModel;

init() {
super.init();
assert('A pageManager is needed for page-renderer', Boolean(this.pageManager));
assert('A draftRegistration xor a revision is needed for page-renderer',
Boolean(this.draftRegistration) !== Boolean(this.revision));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
changeset=this.pageManager.changeset
onInput=@onInput
draftRegistration=@draftRegistration
revision=@revision
}}
/>
{{/each}}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import pathJoin from 'ember-osf-web/utils/path-join';

import AbstractNodeModel from 'ember-osf-web/models/abstract-node';
import DraftRegistrationModel from 'ember-osf-web/models/draft-registration';
import SchemaResponseModel from 'ember-osf-web/models/schema-response';
import styles from './styles';
import template from './template';

Expand All @@ -30,7 +31,8 @@ export default class Files extends Component {
// Required param
changeset!: BufferedChangeset;
schemaBlock!: SchemaBlock;
draftRegistration!: DraftRegistrationModel;
draftRegistration?: DraftRegistrationModel;
revision?: SchemaResponseModel;

@alias('schemaBlock.registrationResponseKey')
valuePath!: string;
Expand All @@ -42,7 +44,15 @@ export default class Files extends Component {

@computed('draftRegistration', 'node.id')
get nodeUrl() {
return pathJoin(baseURL, this.draftRegistration.belongsTo('branchedFrom').id());
if (this.node) {
return pathJoin(baseURL, this.node.id);
}
return '';
}

@computed('revision', 'node', 'currentUserIsReadOnly')
get canEdit() {
return !this.revision && (this.node && !this.currentUserIsReadOnly);
}

didReceiveAttrs() {
Expand All @@ -51,8 +61,8 @@ export default class Files extends Component {
Boolean(this.changeset),
);
assert(
'Registries::SchemaBlockRenderer::Editable::Files requires a draft-registration to render',
Boolean(this.draftRegistration),
'Registries::SchemaBlockRenderer::Editable::Files requires a draft-registration xor a revision to render',
Boolean(this.draftRegistration) !== Boolean(this.revision),
);
assert(
'Registries::SchemaBlockRenderer::Editable::Files requires a valuePath to render',
Expand All @@ -63,7 +73,11 @@ export default class Files extends Component {
Boolean(this.schemaBlock),
);

this.node = this.draftRegistration.belongsTo('branchedFrom').value() as AbstractNodeModel;
if (this.draftRegistration) {
this.node = this.draftRegistration.belongsTo('branchedFrom').value() as AbstractNodeModel;
} else {
this.node = this.revision!.belongsTo('registration').value() as AbstractNodeModel;
}
this.set('selectedFiles', this.changeset.get(this.valuePath) || []);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
@onSelectFile={{action this.onSelectFile}}
@onAddFile={{action this.onAddFile}}
@onDeleteFile={{this.onDeleteFile}}
@canEdit={{and this.node (not this.currentUserIsReadOnly)}}
@canEdit={{this.canEdit}}
disabled={{not this.node}}
...attributes
/>
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
'registries/schema-block-renderer/editable/files'
changeset=@changeset
draftRegistration=@draftRegistration
revision=@revision
onInput=@onInput
)
)}}
2 changes: 1 addition & 1 deletion lib/registries/addon/edit-revision/page/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
>
{{#if navManager.currentPageManager}}
<Registries::PageRenderer
@draftRegistration={{revisionManager.revision}}
@revision={{revisionManager.revision}}
@pageManager={{navManager.currentPageManager}}
@onInput={{perform revisionManager.onPageInput navManager.currentPageManager}}
@node={{this.revisionManager.registration}}
Expand Down
6 changes: 6 additions & 0 deletions mirage/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ export default function(this: Server) {
osfToManyRelationship(this, 'registration', 'subjects', {
only: ['related', 'self'],
});

this.get('/registrations/:parentID/files', nodeFileProviderList); // registration file providers list
this.get('/registrations/:parentID/files/:fileProviderId',
nodeFilesListForProvider); // registration files list for file provider
this.get('/registrations/:parentID/files/:fileProviderId/:folderId',
folderFilesList); // registration folder detail view
osfResource(this, 'subject', { only: ['show'] });

osfNestedResource(this, 'comment', 'reports', {
Expand Down
9 changes: 9 additions & 0 deletions mirage/factories/registration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface RegistrationTraits {
withSubjects: Trait;
withReviewActions: Trait;
withSingleReviewAction: Trait;
withFiles: Trait;
}

const stateAttrs = {
Expand Down Expand Up @@ -259,6 +260,14 @@ export default NodeFactory.extend<MirageRegistration & RegistrationTraits>({
registration.update({ reviewActions });
},
}),
withFiles: trait<MirageRegistration>({
afterCreate(registration, server) {
const count = faker.random.number({ min: 1, max: 5 });
const osfstorage = server.create('file-provider', { target: registration });
const files = server.createList('file', count, { target: registration });
osfstorage.rootFolder.update({ files });
},
}),
});

declare module 'ember-cli-mirage/types/registries/model' {
Expand Down
8 changes: 8 additions & 0 deletions mirage/serializers/registration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ export default class RegistrationSerializer extends ApplicationSerializer<Mirage
},
},
},
files: {
links: {
related: {
href: `${apiUrl}/v2/registrations/${model.id}/files/`,
meta: this.buildRelatedLinkMeta(model, 'files'),
},
},
},
};

if (model.registeredBy) {
Expand Down
4 changes: 4 additions & 0 deletions mirage/views/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ export function nodeFilesListForProvider(this: HandlerContext, schema: Schema) {
let node;
if (this.request.url.includes('draft_nodes')) {
node = schema.draftNodes.find(parentID);
} else if (this.request.url.includes('registrations')) {
node = schema.registrations.find(parentID);
} else {
node = schema.nodes.find(parentID);
}
Expand All @@ -104,6 +106,8 @@ export function nodeFileProviderList(this: HandlerContext, schema: Schema) {
let node: ModelInstance<DraftNode> | ModelInstance<MirageNode>;
if (this.request.url.includes('draft_nodes')) {
node = schema.draftNodes.find(parentID);
} else if (this.request.url.includes('registrations')) {
node = schema.registrations.find(parentID);
} else {
node = schema.nodes.find(parentID);
}
Expand Down
14 changes: 14 additions & 0 deletions tests/integration/components/files-widget/component-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ module('Integration | Component | files-widget', hooks => {
assert.dom('[data-test-file-row]').exists({ count });
});

test('it renders non-editable view for revision', async function(this: ThisTestContext, assert) {
const mirageRegistration = server.create('registration', 'withFiles');
const registration = await this.store.findRecord('registration', mirageRegistration.id);
this.set('registration', registration);
const [osfstorage] = mirageRegistration.files.models;
const count = osfstorage.rootFolder.files.models.length;
await render(hbs`<Files::Widget @node={{this.registration}} @canEdit={{false}} />`);
assert.dom('[data-test-delete-current-folder]').doesNotExist();
assert.dom('[data-test-delete-file]').doesNotExist();
assert.dom('[data-test-files-menu-trigger]').doesNotExist();
assert.dom('[data-test-file-browser-list]').isVisible();
assert.dom('[data-test-file-row]').exists({ count});
});

test('can sort files by name and date', async function(this: ThisTestContext, assert) {
const mirageNode = server.create('node', { currentUserPermissions: Object.values(Permission) });

Expand Down