diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2018-06-05 21:03:31 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2018-06-05 21:03:31 +0200 |
| commit | 746c9f9399487ece15c369c4dd9e3388d415c22c (patch) | |
| tree | 42341d940f3650ea77c85daabc24a15a44769d2b /app/client/dataset | |
| parent | 3b386480bfc8d0b2cc232fec62225d4b4c778c6b (diff) | |
separate dataset stuff from samplernn stuff
Diffstat (limited to 'app/client/dataset')
| -rw-r--r-- | app/client/dataset/dataset.component.js | 124 | ||||
| -rw-r--r-- | app/client/dataset/dataset.form.js | 2 | ||||
| -rw-r--r-- | app/client/dataset/dataset.reducer.js | 226 | ||||
| -rw-r--r-- | app/client/dataset/upload.reducer.js | 52 | ||||
| -rw-r--r-- | app/client/dataset/upload.status.js (renamed from app/client/dataset/dataset.status.js) | 6 |
5 files changed, 363 insertions, 47 deletions
diff --git a/app/client/dataset/dataset.component.js b/app/client/dataset/dataset.component.js new file mode 100644 index 0000000..14ad852 --- /dev/null +++ b/app/client/dataset/dataset.component.js @@ -0,0 +1,124 @@ +import { h, Component } from 'preact' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' +import * as util from '../util' + +import actions from '../actions' + +import DatasetForm from './dataset.form' +import NewDatasetForm from './dataset.new' +import { FileList, FileRow } from '../common/fileList.component' +import Loading from '../common/loading.component' + +class DatasetComponent extends Component { + render(){ + const { loading, progress, module, data, folder, match, history } = this.props + if (loading) { + return <Loading progress={progress} /> + } + if (!data.folders.length) { + console.log('no folders, redirect to /new') + return history.push('/' + module.name + '/new/') + } + if (!folder || !folder.name) return + return ( + <div class='rows params datasets'> + <div class='row row-heading dataset'> + <div class='col'>input</div> + <div class='col'>status</div> + <div class='col'>checkpoint</div> + <div class='col'>output</div> + </div> + {this.renderGroups()} + </div> + ) + } + renderGroups(){ + const { module, data, folder, runner, onPickDataset, onPickFile, datasetActions } = this.props + const { datasetLookup, fileLookup } = data + const { mapFn, sortFn } = util.sort.orderByFn('date desc') + const moduleOnCPU = runner && runner.cpu.task && runner.cpu.task.module === module.name + const moduleOnGPU = runner && runner.gpu.task && runner.gpu.task.module === module.name + const datasets = folder.datasets.map(name => datasetLookup[name]).map(mapFn).sort(sortFn).map(pair => { + const dataset = pair[1] + let status = '' + let isProcessing = false, isFetching = false + if (moduleOnGPU && runner.gpu.task.dataset === dataset) { + status = util.gerund(runner.gpu.task.activity) + isProcessing = true + } else if (moduleOnCPU && runner.cpu.task.activity === 'fetch' && runner.cpu.task.opt.file_id === dataset.input[0]) { + isProcessing = true + isFetching = true + } + return ( + <div key={dataset.name} className='row dataset' onClick={() => onPickDataset && onPickDataset(dataset)}> + {this.props.beforeRow && this.props.beforeRow(dataset)} + <div className='col'> + {!!dataset.input.length && + <FileList + files={dataset.input.map(id => fileLookup[id])} + className='input_files' + fileListClassName='' + rowClassName='input_file' + fields={'name date size delete'} + onClick={onPickFile} + onDelete={(file) => this.onDeleteFile(file)} + /> + } + </div> + <div className={[ + 'col', 'quiet', + (dataset.isBuilt ? 'built' : 'not_built'), + (isProcessing ? 'processing': 'not_processing') + ].join(' ')}> + {this.props.datasetActions && this.props.datasetActions(dataset, isFetching, isProcessing)} + {status} + </div> + <div className='col checkpoint'> + {!!dataset.checkpoints.length && + <FileRow + file={dataset.checkpoints[0]} + fields={'name date epoch'} + className='row checkpoint' + /> + } + </div> + <div className='col'> + {!!dataset.output.length && + <FileList + files={dataset.output.map(id => fileLookup[id])} + orderBy='epoch desc' + fields={'name date epoch size'} + onPickFile={onPickFile} + onDelete={(file) => this.onDeleteFile(file)} + /> + } + </div> + {this.props.afterRow && this.props.afterRow(dataset)} + </div> + ) + }) + return datasets + } + onDeleteFile(file){ + const yes = confirm('Are you sure you want to delete this file?') + if (yes) { + console.log('delete: confirmed') + if (this.props.onDeleteFile) { + console.log('calling custom deletefile function') + this.props.onDeleteFile(file) + } else { + actions.file.destroy(file) + } + } + } +} + +const mapStateToProps = state => ({ + runner: state.system.runner, +}) + +const mapDispatchToProps = (dispatch, ownProps) => ({ +}) + +export default connect(mapStateToProps, mapDispatchToProps)(DatasetComponent) diff --git a/app/client/dataset/dataset.form.js b/app/client/dataset/dataset.form.js index d462d92..255afa0 100644 --- a/app/client/dataset/dataset.form.js +++ b/app/client/dataset/dataset.form.js @@ -67,7 +67,7 @@ class DatasetForm extends Component { } } -const mapStateToProps = state => state.dataset +const mapStateToProps = state => state.upload const mapDispatchToProps = (dispatch, ownProps) => ({ actions: { diff --git a/app/client/dataset/dataset.reducer.js b/app/client/dataset/dataset.reducer.js index 1b7f0b9..287ebb8 100644 --- a/app/client/dataset/dataset.reducer.js +++ b/app/client/dataset/dataset.reducer.js @@ -1,60 +1,200 @@ import types from '../types' -const datasetInitialState = { - loading: false, +/* + Note: + This is a sub-reducer intended to process the folder-file API output from the DB. + Please run this from inside your module reducers :) +*/ + +const datasetInitialState = () => ({ + loading: true, error: null, - status: '', -} + data: null, +}) -const datasetReducer = (state = datasetInitialState, action) => { +const datasetReducer = (state = datasetInitialState(), action) => { switch(action.type) { - case types.folder.upload_loading: + case types.dataset.load: return { - error: null, - loading: true, - status: 'Loading...', - } - case types.folder.upload_error: - return { - error: null, + ...state, loading: false, - status: 'Error uploading :(', + data: action.data, } - case types.folder.upload_progress: - return { - error: null, - loading: true, - status: 'Upload progress ' + action.percent + '%', + + case types.folder.create: + if (action.data.module === 'samplernn') { + return { + ...state, + loading: false, + data: { + folders: state.data.folders.concat([action.data.id]), + folderLookup: { + ...state.data.folderLookup, + [action.data.id]: action.data, + } + }, + } } - case types.folder.upload_waiting: - return { - error: null, - loading: true, - status: 'Waiting for server to finish processing...', + return state + + case types.file.create: + if (action.data.module === 'samplernn') { + console.log(action.data) + let dataset, old_dataset, folder, old_folder + let dataset_name + if (action.data.dataset) { + dataset_name = action.data.dataset + } + else if (action.data.name) { + dataset_name = action.data.name.split('.')[0] + } + else if (action.data.url) { + dataset_name = action.data.url + } + else { + dataset_name = null + } + if (dataset_name in state.data.datasetLookup) { + old_dataset = state.data.datasetLookup[dataset_name] + dataset = { + ...old_dataset, + input: action.data.generated ? old_dataset.input : [action.data.id].concat(old_dataset.input), + output: !action.data.generated ? old_dataset.output : [action.data.id].concat(old_dataset.output), + } + } else { + console.log(action.data.created_at, action.data.date) + dataset = { + name: dataset_name, + date: action.data.created_at || action.data.date, + input: action.data.generated ? [] : [action.data.id], + checkpoints: [], + output: !action.data.generated ? [] : [action.data.id], + } + } + old_folder = state.data.folderLookup[action.data.folder_id] + folder = { + ...old_folder, + datasets: old_folder.datasets.concat([dataset_name]), + files: old_folder.files.concat([action.data.id]), + } + return { + ...state, + loading: false, + data: { + ...state.data, + files: state.data.files.concat([action.data.id]), + folderLookup: { + ...state.data.folderLookup, + [action.data.folder_id]: folder, + }, + fileLookup: { + ...state.data.fileLookup, + [action.data.id]: action.data, + }, + datasetLookup: { + ...state.data.datasetLookup, + [dataset_name]: dataset, + }, + } + } } - case types.folder.upload_complete: - return { - error: null, - loading: false, - status: 'Upload complete', + return state + + case types.file.update: + if (action.data.module === 'samplernn') { + let old_dataset; + let new_dataset = state.data.datasetLookup[action.data.dataset] + let old_file = state.data.fileLookup[action.data.id] + let new_dataset_update; + if (old_file && action.data.dataset !== old_file.dataset) { + if (state.data.datasetLookup[old_file.dataset]) { + old_dataset = state.data.datasetLookup[old_file.dataset] + old_dataset_update = { + ...old_dataset, + input: old_dataset.input.filter(id => id !== action.data.id), + output: old_dataset.output.filter(id => id !== action.data.id), + } + } + new_dataset_update = { + ...new_dataset, + input: action.data.generated ? [] : [action.data.id], + output: !action.data.generated ? [] : [action.data.id], + } + } + console.log('old_dataset', old_dataset_update.name) + console.log('new_dataset', new_dataset_update.name) + return { + ...state, + loading: false, + data: { + ...state.data, + datasetLookup: old_dataset ? { + ...state.data.datasetLookup, + [old_dataset.name]: old_dataset_update, + [new_dataset.name]: new_dataset_update, + } : new_dataset_update ? { + ...state.data.datasetLookup, + [new_dataset.name]: new_dataset_update, + } : state.data.datasetLookup, + fileLookup: { + ...state.data.fileLookup, + [action.data.id]: action.data, + }, + } + } } - case types.file.create_loading: - return { - error: null, - loading: true, - status: 'Creating file...' + return state + + case types.file.destroy: + if (action.data.module === 'samplernn') { + // delete the key from fileLookup + let fileLookup = { + ...state.data.fileLookup + } + let datasetLookup = { + ...state.data.datasetLookup + } + let folderLookup = { + ...state.data.folderLookup + } + let old_file = fileLookup[action.data.id] + if (!old_file) return state + let old_dataset = state.data.datasetLookup[old_file.dataset] + let dataset + if (old_dataset) { + dataset = { + ...old_dataset, + input: old_dataset.input.filter(id => id !== old_file.id), + output: old_dataset.output.filter(id => id !== old_file.id), + } + if (! dataset.input.length && ! dataset.checkpoints.length && ! dataset.output.length) { + delete datasetLookup[old_file.dataset] + let old_folder = folderLookup[old_file.folder_id] + folderLookup[old_file.folder_id] = { + ...old_folder, + datasets: old_folder.datasets.filter(name => name !== old_file.dataset) + } + } else { + console.log('dataset just needs sweeping') + datasetLookup[old_file.dataset] = dataset + } + } + delete fileLookup[old_file.id] + + return { + ...state, + loading: false, + data: { + ...state.data, + folderLookup, + fileLookup, + datasetLookup, + } + } } - case types.socket.status: - return datasetSocket(state, action.data) - default: return state - } -} -const datasetSocket = (state, action) => { - console.log(action) - switch (action.key) { - default: + default: return state } } diff --git a/app/client/dataset/upload.reducer.js b/app/client/dataset/upload.reducer.js new file mode 100644 index 0000000..e28a18e --- /dev/null +++ b/app/client/dataset/upload.reducer.js @@ -0,0 +1,52 @@ +import types from '../types' + +const uploadInitialState = { + loading: false, + error: null, + status: '', +} + +const uploadReducer = (state = uploadInitialState, action) => { + switch(action.type) { + case types.folder.upload_loading: + return { + error: null, + loading: true, + status: 'Loading...', + } + case types.folder.upload_error: + return { + error: null, + loading: false, + status: 'Error uploading :(', + } + case types.folder.upload_progress: + return { + error: null, + loading: true, + status: 'Upload progress ' + action.percent + '%', + } + case types.folder.upload_waiting: + return { + error: null, + loading: true, + status: 'Waiting for server to finish processing...', + } + case types.folder.upload_complete: + return { + error: null, + loading: false, + status: 'Upload complete', + } + case types.file.create_loading: + return { + error: null, + loading: true, + status: 'Creating file...' + } + default: + return state + } +} + +export default uploadReducer diff --git a/app/client/dataset/dataset.status.js b/app/client/dataset/upload.status.js index 9e9e56f..3fce4fa 100644 --- a/app/client/dataset/dataset.status.js +++ b/app/client/dataset/upload.status.js @@ -4,7 +4,7 @@ import { connect } from 'react-redux' import Loading from '../common/loading.component' -function DatasetStatus (props) { +function UploadStatus (props) { return ( <div class='status'> {props.status} @@ -12,8 +12,8 @@ function DatasetStatus (props) { ) } -const mapStateToProps = state => state.dataset +const mapStateToProps = state => state.upload const mapDispatchToProps = (dispatch, ownProps) => ({}) -export default connect(mapStateToProps, mapDispatchToProps)(DatasetStatus) +export default connect(mapStateToProps, mapDispatchToProps)(UploadStatus) |
