Skip to content
This repository has been archived by the owner on Jan 28, 2020. It is now read-only.

Commit

Permalink
# 0.1.3
Browse files Browse the repository at this point in the history
  - Features
    - Support Copy & Pate
    - Add row
    - Auto reload after add & update row
  • Loading branch information
deptno committed Apr 7, 2018
1 parent c1da209 commit 84b6cd1
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 83 deletions.
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Dynamon is GUI client for DynamoDB

---

under development(unstable)
> unstable (under development)
[![](https://user-images.githubusercontent.com/1223020/38453064-7a2d421c-3a8a-11e8-821f-c607fff85642.png)](https://www.youtube.com/watch?v=UI9xyrAKAg0&feature=youtu.be)
:eyes: Click to watch
Expand All @@ -22,3 +22,28 @@ checkout development version <https://github.com/deptno/dynamon/releases>
* [ ] Nested JSON
* [x] JSON view
* [x] Edit record

## changelog

##### 0.1.3

* Features
* Support Copy & Pate
* Add row
* Auto reload after add & update row

##### 0.1.2

* Miscellaneous
* add Github, Report issue link

##### 0.1.1

* Features
* Table schema view
* support icon
* can update row and cell
* Fixes
* unexpected button click event bubbling

##### 0.1.0 - dynamon is born.
67 changes: 67 additions & 0 deletions packages/dynamon-fe/components/DynamoTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import * as React from 'react'
import {StackableJsonTableComponent} from './StackableJsonTable'
import {Popover} from '@blueprintjs/core'
import {TableStateDescription} from './TableStateDescription'
import {JsonComponent} from './Json'
import {connect} from 'react-redux'
import {actions, Actions, RootState} from '../redux'

export class DynamoTableComponent extends React.Component<Props, State> {
render() {
const {table, records, onItemSelected, onRefresh} = this.props

return (
<div>
<label className="pt-label pt-inline">
Records
{table && (
<Popover>
<button className="pt-button pt-icon-add pt-intent-primary pt-inline pt-minimal"/>
<JsonComponent
title="Add record"
src={table.KeySchema.reduce((p, c) => {
p[c.AttributeName] = `input valid(type: string) ${c.AttributeName}`
return p
}, {})}
onEdit={this.handleOnEdit}
/>
</Popover>
)}
<button
onClick={onRefresh}
className="pt-button pt-icon-refresh pt-intent-danger pt-inline pt-minimal"
disabled={!records}
/>
</label>
{records
? records.length > 0
? <StackableJsonTableComponent collection={records} onItemSelected={onItemSelected}/>
: <TableStateDescription description="Empty"/>
: <TableStateDescription description="Select Table"/>
}
</div>
)
}

handleOnEdit = async (prev, next) => {
await this.props.createRecord(this.props.table.TableName, next)
this.props.readRecords(this.props.table.TableName)
}
}

const mapStateToProps = (state: RootState) => state
const mapDispatchToProps = actions
export const DynamoTable = connect<StateProps, DispatchProps, OwnProps>(mapStateToProps, mapDispatchToProps)(DynamoTableComponent)

interface StateProps extends RootState {
}
interface DispatchProps extends Actions {
}
interface OwnProps {
onItemSelected?(json): void
onRefresh?(): void
}
interface Props extends StateProps, DispatchProps, OwnProps {
}
interface State {
}
42 changes: 12 additions & 30 deletions packages/dynamon-fe/components/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from 'react'
import {connect} from 'react-redux'
import {StackableJsonTableComponent} from './StackableJsonTable'
import {Actions, actions, RootState} from '../redux'
import {SelectComponent} from './Select'
import {JsonComponent} from './Json'
import {Icon} from '@blueprintjs/core'
import {DynamoTable} from './DynamoTable'
import {LinksComponent} from './Links'

export class HomeComponent extends React.Component<Props, State> {
private selectedTable = '__'
Expand All @@ -13,18 +13,11 @@ export class HomeComponent extends React.Component<Props, State> {
}

render() {
const {loadingEndpoints, endpoints, tables, records} = this.props
const {loadingEndpoints, endpoints, tables, records, table} = this.props
const countTables = tables.length
return (
<div>
<div className="pt-ui-text" style={{marginBottom: '10px'}}>
<a target="_blank" href="https://github.com/deptno/dynamon">
<Icon icon="git-repo"/> Github
</a> &nbsp;
<a target="_blank" href="https://github.com/deptno/dynamon/issues/new">
<Icon icon="issue-new"/> Report issue
</a>
</div>
<LinksComponent/>
<div className="pt-control-group pt-fill">
<SelectComponent
title="Endpoint"
Expand All @@ -37,29 +30,17 @@ export class HomeComponent extends React.Component<Props, State> {
title="Table"
description={countTables > 0 ? `Select table from ${countTables} tables` : 'none'}
onChange={this.handleOnTableChange}
onZoom={() => {console.log(this.props, this.state); debugger}}
onZoom={() => {
console.log(this.props, this.state)
debugger
}}
disabled={countTables === 0}
>
{tables.map(({TableName}) => <option key={TableName} value={TableName}>{TableName}</option>)}
</SelectComponent>
</div>
<JsonComponent src={this.state.json} onEdit={this.handleJsonEdit}/>
{records
?
<StackableJsonTableComponent
collection={records}
onItemSelected={this.handleOnItemSelected}
onRefresh={this.handleOnRefreshRecords}
/>
: (
<div className="pt-non-ideal-state" style={{marginTop: '45px'}}>
<div className="pt-non-ideal-state-visual pt-non-ideal-state-icon">
<span className="pt-icon pt-icon-th"></span>
</div>
<h4 className="pt-non-ideal-state-title">Select Table</h4>
</div>
)
}
<DynamoTable onItemSelected={this.handleOnItemSelected} onRefresh={this.handleOnRefreshRecords}/>
</div>
)
}
Expand All @@ -68,9 +49,10 @@ export class HomeComponent extends React.Component<Props, State> {
this.props.readEndpoints()
}

handleJsonEdit = (prev, next) => {
handleJsonEdit = async (prev, next) => {
console.log('before edit', prev, 'after edit', next)
this.props.updateRecord(this.selectedTable, next)
await this.props.updateRecord(this.selectedTable, next)
this.props.readRecords(this.props.table.TableName)
if (!next) {
if (confirm('delete row?')) {

Expand Down
6 changes: 5 additions & 1 deletion packages/dynamon-fe/components/Json.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import RJV, {RJVModified} from 'react-json-view'
import classnames from 'classnames'

export class JsonComponent extends React.Component<Props, State> {
static defaultProps = {
title: 'JSON'
}
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.src !== prevState.src) {
return {
Expand All @@ -25,7 +28,7 @@ export class JsonComponent extends React.Component<Props, State> {
return (
<div style={expend ? {} : {maxHeight: '300px', overflow: 'scroll'}}>
<label className="pt-label pt-inline" style={{marginTop: '10px', marginBottom: 0}}>
JSON
{this.props.title}
<button
className={classnames('pt-button pt-icon-confirm pt-minimal', {'pt-intent-success': dirty})}
onClick={this.handleApplyChanges}
Expand Down Expand Up @@ -77,6 +80,7 @@ export class JsonComponent extends React.Component<Props, State> {
}

interface Props {
title?: string
src: Object | Array<any>
onEdit?(prev, next): void
}
Expand Down
22 changes: 22 additions & 0 deletions packages/dynamon-fe/components/Links.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react'
import {Icon} from '@blueprintjs/core'

export class LinksComponent extends React.Component<Props, State> {
render() {
return (
<div className="pt-ui-text" style={{marginBottom: '10px'}}>
<a target="_blank" href="https://github.com/deptno/dynamon">
<Icon icon="git-repo"/> Github
</a> &nbsp;
<a target="_blank" href="https://github.com/deptno/dynamon/issues/new">
<Icon icon="issue-new"/> Report issue
</a>
</div>
)
}
}

interface Props {
}
interface State {
}
32 changes: 10 additions & 22 deletions packages/dynamon-fe/components/StackableJsonTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,16 @@ export class StackableJsonTableComponent extends React.Component<Props, State> {
}

render() {
return (
<div>
<label className="pt-label pt-inline">
Records
<button
onClick={this.props.onRefresh}
className="pt-button pt-icon-refresh pt-intent-danger pt-inline pt-minimal"
/>
</label>
{this.state.stack.map(({collection, keepHeader}, i) => (
<BlueprintDJTComponent
key={i}
keepHeader={keepHeader}
data={collection}
onRowClick={this.handleRowClick}
onEnterArray={this.handleOnEnterArray}
onItemSelected={this.handleOnItemSelected}
/>
))}
</div>
)
return this.state.stack.map(({collection, keepHeader}, i) => (
<BlueprintDJTComponent
key={i}
keepHeader={keepHeader}
data={collection}
onRowClick={this.handleRowClick}
onEnterArray={this.handleOnEnterArray}
onItemSelected={this.handleOnItemSelected}
/>
))
}

handleOnItemSelected = (item = this.props.collection) => {
Expand Down Expand Up @@ -66,7 +55,6 @@ interface Props {
keys?: string[]
collection: any[]
onItemSelected?(item): void
onRefresh?(): void
}
interface State {
stack: Stack[]
Expand Down
13 changes: 13 additions & 0 deletions packages/dynamon-fe/components/TableStateDescription.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react'

export const TableStateDescription: React.SFC<Props> = props =>
<div className="pt-non-ideal-state" style={{marginTop: '45px'}}>
<div className="pt-non-ideal-state-visual pt-non-ideal-state-icon">
<span className="pt-icon pt-icon-th"></span>
</div>
<h4 className="pt-non-ideal-state-title">{props.description}</h4>
</div>

interface Props {
description: string
}
47 changes: 22 additions & 25 deletions packages/dynamon-fe/redux/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import TableDescription = DocumentClient.TableDescription
import ItemList = DocumentClient.ItemList

const defaultState: RootState = Object.freeze({
endpoints: [],
tables: [],
records: null,
table : null,
loadingEndpoints: false
endpoints : [],
tables : [],
records : null,
table : null,
loadingEndpoints: false,
})
export const reducer = (state = defaultState, action: ReturnType<Actions[keyof Actions]>) => {
if (action.type.startsWith('@')) {
Expand All @@ -21,9 +21,6 @@ export const reducer = (state = defaultState, action: ReturnType<Actions[keyof A
return {...state, tables: action.payload}
case ActionTypes.READ_RECORDS:
return {...state, records: action.payload}
case ActionTypes.UPDATE_RECORD:
console.log(action)
return state
}
}
switch (action.type) {
Expand All @@ -34,7 +31,6 @@ export const reducer = (state = defaultState, action: ReturnType<Actions[keyof A
case ActionTypes.READ_TABLES:
return {...state, tables: defaultState.tables}
case ActionTypes.SET_TABLE:
debugger
return {...state, table: state.tables.find(t => t.TableName === action.payload)}
}
return state
Expand All @@ -44,25 +40,25 @@ export const reducer = (state = defaultState, action: ReturnType<Actions[keyof A
action types
*/
enum ActionTypes {
READ_ENDPOINTS = 'read endpoints',
READ_ENDPOINTS = 'read endpoints',

READ_TABLES = 'read tables',
READ_TABLES = 'read tables',

CREATE_TABLE = 'create table',
READ_TABLE = 'read table',
UPDATE_TABLE = 'update table',
DELETE_TABLE = 'delete table',
CREATE_TABLE = 'create table',
READ_TABLE = 'read table',
UPDATE_TABLE = 'update table',
DELETE_TABLE = 'delete table',

CREATE_RECORDS = 'create records',
READ_RECORDS = 'read records',
READ_RECORDS = 'read records',
UPDATE_RECORDS = 'update records',
DELETE_RECORDS = 'delete records',

CREATE_RECORD = 'create record',
UPDATE_RECORD = 'update record',
DELETE_RECORD = 'delete record',
CREATE_RECORD = 'create record',
UPDATE_RECORD = 'update record',
DELETE_RECORD = 'delete record',

SET_TABLE = 'set table'
SET_TABLE = 'set table'
}

/*
Expand All @@ -71,11 +67,12 @@ enum ActionTypes {
export const actions = {
setTable: (tableName?: string) => action(ActionTypes.SET_TABLE, tableName),

readEndpoints : () => universalAction(ActionTypes.READ_ENDPOINTS),
readTables : (server: Endpoint) => universalAction(ActionTypes.READ_TABLES, server),
readTable: (tableName?: string) => universalAction(ActionTypes.READ_TABLE, tableName),
readRecords: (tableName: string) => universalAction(ActionTypes.READ_RECORDS, tableName),
updateRecord: (tableName: string, record: any) => universalAction(ActionTypes.UPDATE_RECORD, {tableName, record})
readEndpoints: () => universalAction(ActionTypes.READ_ENDPOINTS),
readTables : (server: Endpoint) => universalAction(ActionTypes.READ_TABLES, server),
readTable : (tableName?: string) => universalAction(ActionTypes.READ_TABLE, tableName),
readRecords : (tableName: string) => universalAction(ActionTypes.READ_RECORDS, tableName),
createRecord : (tableName: string, record: any) => universalAction(ActionTypes.CREATE_RECORD, {tableName, record}),
updateRecord : (tableName: string, record: any) => universalAction(ActionTypes.UPDATE_RECORD, {tableName, record}),
}

/*
Expand Down
Loading

0 comments on commit 84b6cd1

Please sign in to comment.