Skip to content

Commit

Permalink
[TASK] Add copy/move/delete resoruces
Browse files Browse the repository at this point in the history
Fixes: #23, #31, #83
  • Loading branch information
NeoBlack committed Apr 4, 2019
1 parent 71eb3b2 commit 42882bb
Show file tree
Hide file tree
Showing 30 changed files with 7,093 additions and 17,832 deletions.
1 change: 1 addition & 0 deletions Build/Vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"watch-lib": "vue-cli-service build --watch --target lib --name filelist ./src/main.ts"
},
"dependencies": {
"@types/jquery": "^3.3.29",
"axios": "^0.18.0",
"vue": "^2.6.6",
"vue-class-component": "^6.0.0",
Expand Down
13 changes: 7 additions & 6 deletions Build/Vue/src/components/AllSelector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {Component, Prop, Vue} from 'vue-property-decorator';
import {VNode} from 'vue';
import {Mutation, State} from 'vuex-class';
import {Mutations} from '@/enums/Mutations';
import {ResourceInterface} from '@/interfaces/ResourceInterface';

@Component
export default class AllSelector extends Vue {
Expand All @@ -16,10 +17,10 @@ export default class AllSelector extends Vue {
unselectItems: any;

@State
selected!: Array<object>;
selected!: Array<ResourceInterface>;

@Prop()
listOfIdentifiers!: Array<String>;
listOfResources!: Array<ResourceInterface>;

constructor(props: any) {
super(props);
Expand All @@ -28,17 +29,17 @@ export default class AllSelector extends Vue {
private render(): VNode {
// fix me, I'm ugly
return (
<a href='#' onClick={(event: Event) => this.toggleSelect(event, this.listOfIdentifiers)} class='btn btn-sm btn-default'>
<a href='#' onClick={(event: Event) => this.toggleSelect(event, this.listOfResources)} class='btn btn-sm btn-default'>
<i class='fa fa-check-square' v-show={this.isSelected} />
<i class='fa fa-square-o' v-show={!this.isSelected} />
</a>
);
}

private toggleSelect(event: Event, listOfIdentifiers: Array<String>): void {
private toggleSelect(event: Event, listOfResources: Array<ResourceInterface>): void {
event.stopPropagation();
this.selected.length > 0
? this.unselectItems(listOfIdentifiers)
: this.selectItems(listOfIdentifiers);
? this.unselectItems(listOfResources)
: this.selectItems(listOfResources);
}
}
191 changes: 185 additions & 6 deletions Build/Vue/src/components/ButtonBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,193 @@
import {Component, Vue} from 'vue-property-decorator';
import {VNode} from 'vue';
import {Action, Mutation, State} from 'vuex-class';
import {AjaxRoutes} from '@/enums/AjaxRoutes';
import {Mutations} from '@/enums/Mutations';
import CopyMoveModal from '@/components/CopyMoveModal';
import {CopyMoveRequestInterface} from '@/interfaces/request/CopyMoveRequestInterface';
import {ResourceInterface} from '@/interfaces/ResourceInterface';
import client from '@/services/http/Typo3Client';
import Modal from 'TYPO3/CMS/Backend/Modal';
import {DeleteRequestInterface} from '@/interfaces/request/DeleteRequestInterface';
import {DownloadRequestInterface} from '@/interfaces/request/DownloadRequestInterface';

@Component
export default class ButtonBar extends Vue {
constructor(props: any) {
super(props);
@Action(AjaxRoutes.damGetFolderItems)
fetchData: any;

@Mutation(Mutations.SET_MODAL_CONTENT)
setModalContent!: Function;

@Mutation(Mutations.NAVIGATE)
navigate!: Function;

@State
selected!: Array<ResourceInterface>;

@State
current!: string;

private modal: any;

constructor(props: any) {
super(props);
}

private async copyResources(request: CopyMoveRequestInterface): Promise<any> {
const identifiers: Array<string> = [];
Object.values(request.resources).map((item: ResourceInterface) => {
identifiers.push(item.identifier);
});

const response = await client.get(
TYPO3.settings.ajaxUrls[AjaxRoutes.damCopyResources]
+ '&conflictMode=rename'
+ '&identifiers[]=' + identifiers.join('&identifiers[]=')
+ '&targetFolderIdentifier=' + request.target,
);

if (response.status === 200) {
this.modal.trigger('modal-dismiss');
this.fetchData(request.target);
this.navigate(request.target);
}
}

private async moveResources(request: CopyMoveRequestInterface): Promise<any> {
const identifiers: Array<string> = [];
Object.values(request.resources).map((item: ResourceInterface) => {
identifiers.push(item.identifier);
});

const response = await client.get(
TYPO3.settings.ajaxUrls[AjaxRoutes.damMoveResources]
+ '&conflictMode=rename'
+ '&identifiers[]=' + identifiers.join('&identifiers[]=')
+ '&targetFolderIdentifier=' + request.target,
);

if (response.status === 200) {
this.modal.trigger('modal-dismiss');
this.fetchData(request.target);
this.navigate(request.target);
}
private render(): VNode {
return (
<div><button>ButtonBar</button></div>
);
}

private async deleteResources(request: DeleteRequestInterface): Promise<any> {
const identifiers: Array<string> = [];
Object.values(request.resources).map((item: ResourceInterface) => {
identifiers.push(item.identifier);
});

const response = await client.get(
TYPO3.settings.ajaxUrls[AjaxRoutes.damDeleteResources]
+ '&identifiers[]=' + identifiers.join('&identifiers[]='),
);

if (response.status === 200) {
this.modal.trigger('modal-dismiss');
this.fetchData(this.current);
this.navigate(this.current);
}
}

private async downloadResources(request: DownloadRequestInterface): Promise<any> {
const identifiers: Array<string> = [];
Object.values(request.resources).map((item: ResourceInterface) => {
identifiers.push(item.identifier);
});

const response = await client.get(
TYPO3.settings.ajaxUrls[AjaxRoutes.damPrepareDownload]
+ '&identifiers[]=' + identifiers.join('&identifiers[]='),
);
}

private selectTarget(action: Function): void {
this.setModalContent(<CopyMoveModal />);
let content: any = jQuery('#vue-modalContent');
this.modal = Modal.advanced({
content: content,
additionalCssClasses: ['modal-select-target'],
buttons: [
{
btnClass: 'btn-default',
dataAttributes: {
method: 'dismiss',
},
icon: 'actions-close',
text: 'Cancel',
},
{
btnClass: 'btn-primary',
dataAttributes: {
method: 'select',
},
text: 'Select target',
},
],
callback: (currentModal: any): void => {
currentModal.on('button.clicked', (e: any): void => {
const method = $(e.target).data('method');
if (method === 'dismiss') {
currentModal.trigger('modal-dismiss');
}
if (method === 'select') {
const target: string = $(e.currentTarget).find('.list-tree .list-tree-group.active').data('identifier');
action({
'resources': this.selected,
'target': target,
});
// currentModal.trigger('modal-dismiss');
}
});
},
title: 'Select target folder',
});
}

private confirm(action: Function): void {
this.modal = Modal.confirm('Are you sure?', 'Do you want delete the selected resources?')
.on('confirm.button.cancel', (): void => {
this.modal.trigger('modal-dismiss');
})
.on('confirm.button.ok', (): void => {
action({
'resources': this.selected,
});
});
}


private render(): VNode {
const disabled = this.selected.length === 0;
const cssClasses = 'btn btn-default' + (disabled ? ' disabled' : '');
const moveResources = (e: Event) => {
e.stopPropagation();
this.selectTarget(this.moveResources);
};
const copyResources = (e: Event) => {
e.stopPropagation();
this.selectTarget(this.copyResources);
};
const deleteResources = (e: Event) => {
e.stopPropagation();
this.confirm(this.deleteResources);
};
const downloadResources = (e: Event) => {
e.stopPropagation();
this.downloadResources({
'resources': this.selected,
});
};
return (
<div class='btn-group'>
<a href='#' class={cssClasses} disabled={disabled} onClick={downloadResources}><i class='fa fa-download'/> Download</a>
<a href='#' class={cssClasses} disabled={disabled} onClick={deleteResources}><i class='fa fa-trash'/> Delete</a>
<a href='#' class={cssClasses} disabled={disabled} onClick={moveResources}><i class='fa fa-crosshairs'/> Move to</a>
<a href='#' class={cssClasses} disabled={disabled} onClick={copyResources}><i class='fa fa-clipboard'/> Copy to</a>
</div>
);
}
}
3 changes: 2 additions & 1 deletion Build/Vue/src/components/ContentPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {FolderInterface} from '@/interfaces/FolderInterface';
import {FileInterface} from '@/interfaces/FileInterface';
import {ImageInterface} from '@/interfaces/ImageInterface';
import {ResourceInterface} from '@/interfaces/ResourceInterface';
import ButtonBar from '@/components/ButtonBar';

@Component
export default class ContentPanel extends Vue {
Expand Down Expand Up @@ -86,7 +87,7 @@ export default class ContentPanel extends Vue {
return (
<div class='typo3-filelist-contentpanel'>
<DocHeader>
<template slot='topBarLeft'><TreeToggle/><ViewSelector/></template>
<template slot='topBarLeft'><TreeToggle/><ViewSelector/><ButtonBar/></template>
<template slot='topBarRight'><SortingSelector/></template>
<template slot='bottomBarLeft'><Breadcrumb/></template>
<template slot='bottomBarRight'><SelectIndicator/></template>
Expand Down
Loading

0 comments on commit 42882bb

Please sign in to comment.