@@ -4,7 +4,7 @@ | |||||
"author": "Guillaume Vincent <guillaume@oslab.fr>", | "author": "Guillaume Vincent <guillaume@oslab.fr>", | ||||
"private": true, | "private": true, | ||||
"scripts": { | "scripts": { | ||||
"dev": "webpack-dev-server --hot --host 0.0.0.0", | |||||
"dev": "webpack-dev-server --inline --hot --host 0.0.0.0", | |||||
"build": "NODE_ENV=production webpack --display-error-details --progress --hide-modules", | "build": "NODE_ENV=production webpack --display-error-details --progress --hide-modules", | ||||
"test": "ava test --compilers js:babel-register" | "test": "ava test --compilers js:babel-register" | ||||
}, | }, | ||||
@@ -26,6 +26,7 @@ | |||||
"file-loader": "^0.9.0", | "file-loader": "^0.9.0", | ||||
"font-awesome": "^4.6.3", | "font-awesome": "^4.6.3", | ||||
"hint.css": "^2.3.2", | "hint.css": "^2.3.2", | ||||
"jquery": "^3.1.1", | |||||
"json-loader": "^0.5.4", | "json-loader": "^0.5.4", | ||||
"jwt-decode": "^2.1.0", | "jwt-decode": "^2.1.0", | ||||
"lesspass": "^4.0.4", | "lesspass": "^4.0.4", | ||||
@@ -0,0 +1,35 @@ | |||||
<style> | |||||
.fa-white { | |||||
color: #ffffff; | |||||
} | |||||
</style> | |||||
<template> | |||||
<div id="delete-button"> | |||||
<button type="button" class="btn btn-danger" v-on:click="confirm"> | |||||
<i class="fa-white fa fa-trash"></i> | |||||
</button> | |||||
</div> | |||||
</template> | |||||
<script type="text/ecmascript-6"> | |||||
export default { | |||||
data() { | |||||
return { | |||||
pending: false | |||||
} | |||||
}, | |||||
props: { | |||||
promise: {type: Function, required: true}, | |||||
text: {type: String, required: true}, | |||||
object: {type: Object, required: true} | |||||
}, | |||||
methods: { | |||||
confirm() { | |||||
this.pending = true; | |||||
var response = confirm(this.text); | |||||
if (response == true) { | |||||
this.promise(this.object); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
</script> |
@@ -25,22 +25,37 @@ | |||||
</form> | </form> | ||||
<div id="passwords" class="row" v-if="!loading"> | <div id="passwords" class="row" v-if="!loading"> | ||||
<div class="col-xs-12"> | <div class="col-xs-12"> | ||||
<div class="col-xs-12" v-if="passwords.length === 0"> | |||||
You don't have any passwords saved in your database. | |||||
<br> | |||||
<router-link :to="{ name: 'home'}">Would you like to create one ?</router-link> | |||||
</div> | |||||
<router-link class="list-group-item list-group-item-action" | |||||
:to="{ name: 'password', params: { passwordId: password.id }}" | |||||
v-for="password in filteredPasswords"> | |||||
<h5 class="list-group-item-heading">{{password.site}}</h5> | |||||
<p class="list-group-item-text">{{password.login}}</p> | |||||
</router-link> | |||||
<table class="table"> | |||||
<tbody> | |||||
<tr v-if="passwords.length === 0"> | |||||
<td> | |||||
You don't have any passwords saved in your database. | |||||
<br> | |||||
<router-link :to="{ name: 'home'}">Would you like to create one ?</router-link> | |||||
</td> | |||||
</tr> | |||||
<tr v-for="password in filteredPasswords"> | |||||
<td> | |||||
<router-link :to="{ name: 'password', params: { passwordId: password.id }}"> | |||||
{{password.site}} | |||||
</router-link> | |||||
<br> | |||||
{{password.login}} | |||||
</td> | |||||
<td class="text-xs-right"> | |||||
<delete-button :promise="deletePassword" :object="password" | |||||
text="Are you sure you want to delete this password ?"> | |||||
</delete-button> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
<script type="text/ecmascript-6"> | <script type="text/ecmascript-6"> | ||||
import DeleteButton from './DeleteButton'; | |||||
import Storage from '../api/storage'; | import Storage from '../api/storage'; | ||||
import HTTP from '../api/http'; | import HTTP from '../api/http'; | ||||
@@ -55,12 +70,20 @@ | |||||
searchQuery: '' | searchQuery: '' | ||||
} | } | ||||
}, | }, | ||||
components: { | |||||
DeleteButton | |||||
}, | |||||
methods: { | methods: { | ||||
fetchPasswords(){ | fetchPasswords(){ | ||||
Passwords.all().then(response => { | Passwords.all().then(response => { | ||||
this.passwords = response.data.results; | this.passwords = response.data.results; | ||||
this.loading = false; | this.loading = false; | ||||
}); | }); | ||||
}, | |||||
deletePassword(password){ | |||||
return Passwords.remove({id: password.id}).then(() => { | |||||
this.fetchPasswords(); | |||||
}); | |||||
} | } | ||||
}, | }, | ||||
computed: { | computed: { | ||||
@@ -4,8 +4,8 @@ import 'bootstrap/dist/css/bootstrap.css'; | |||||
import 'font-awesome/css/font-awesome.css'; | import 'font-awesome/css/font-awesome.css'; | ||||
import 'hint.css/hint.css'; | import 'hint.css/hint.css'; | ||||
import App from './App'; | import App from './App'; | ||||
import 'bootstrap/dist/js/bootstrap.min'; | |||||
import Store from './store' | |||||
import 'bootstrap/dist/js/bootstrap'; | |||||
import Store from './store'; | |||||
import Storage from './api/storage'; | import Storage from './api/storage'; | ||||
import router from './routes'; | import router from './routes'; | ||||
@@ -1,6 +1,6 @@ | |||||
var webpack = require('webpack'); | var webpack = require('webpack'); | ||||
var path = require('path'); | var path = require('path'); | ||||
var ExtractTextPlugin = require("extract-text-webpack-plugin"); | |||||
var ExtractTextPlugin = require('extract-text-webpack-plugin'); | |||||
module.exports = { | module.exports = { | ||||
entry: './src/main.js', | entry: './src/main.js', | ||||
@@ -13,7 +13,8 @@ module.exports = { | |||||
extensions: ['', '.js', '.vue'], | extensions: ['', '.js', '.vue'], | ||||
fallback: [path.join(__dirname, 'node_modules')], | fallback: [path.join(__dirname, 'node_modules')], | ||||
alias: { | alias: { | ||||
src: path.resolve(__dirname, './src') | |||||
src: path.resolve(__dirname, './src'), | |||||
jquery: 'jquery/src/jquery' | |||||
} | } | ||||
}, | }, | ||||
resolveLoader: { | resolveLoader: { | ||||
@@ -23,26 +24,20 @@ module.exports = { | |||||
loaders: [ | loaders: [ | ||||
{test: /\.vue$/, loader: 'vue-loader'}, | {test: /\.vue$/, loader: 'vue-loader'}, | ||||
{test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'}, | {test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'}, | ||||
{test: /\.json$/, loader: "json-loader"}, | |||||
{test: /\.(png|jpg|jpeg|gif)$/, loader: 'url?limit=10000&name=images/[name].[ext]',}, | {test: /\.(png|jpg|jpeg|gif)$/, loader: 'url?limit=10000&name=images/[name].[ext]',}, | ||||
{test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader")}, | |||||
{test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader')}, | |||||
{test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/, loader: 'file-loader'} | {test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/, loader: 'file-loader'} | ||||
] | ] | ||||
}, | }, | ||||
plugins: [ | plugins: [ | ||||
new ExtractTextPlugin("styles.css"), | |||||
new ExtractTextPlugin('styles.css'), | |||||
new webpack.ProvidePlugin({ | new webpack.ProvidePlugin({ | ||||
$: 'jquery', | $: 'jquery', | ||||
jQuery: 'jquery', | jQuery: 'jquery', | ||||
'window.jQuery': 'jquery', | 'window.jQuery': 'jquery', | ||||
'Tether': 'tether', | |||||
'window.Tether': 'tether' | 'window.Tether': 'tether' | ||||
}) | }) | ||||
], | ], | ||||
devServer: { | |||||
historyApiFallback: true, | |||||
noInfo: true | |||||
}, | |||||
devtool: '#eval-source-map' | devtool: '#eval-source-map' | ||||
}; | }; | ||||
@@ -50,11 +45,6 @@ if (process.env.NODE_ENV === 'production') { | |||||
module.exports.devtool = false; | module.exports.devtool = false; | ||||
module.exports.output.publicPath = ''; | module.exports.output.publicPath = ''; | ||||
module.exports.plugins = (module.exports.plugins || []).concat([ | module.exports.plugins = (module.exports.plugins || []).concat([ | ||||
new webpack.DefinePlugin({ | |||||
'process.env': { | |||||
NODE_ENV: '"production"' | |||||
} | |||||
}), | |||||
new webpack.optimize.DedupePlugin(), | new webpack.optimize.DedupePlugin(), | ||||
new webpack.optimize.OccurrenceOrderPlugin(), | new webpack.optimize.OccurrenceOrderPlugin(), | ||||
new webpack.optimize.UglifyJsPlugin({ | new webpack.optimize.UglifyJsPlugin({ | ||||