diff --git a/package-lock.json b/package-lock.json
index 374b996..00a40a6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1186,6 +1186,32 @@
"find-up": "^2.1.0"
}
},
+ "@fortawesome/fontawesome-common-types": {
+ "version": "0.2.24",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.24.tgz",
+ "integrity": "sha512-IPBT/1LdUVQpHcqdrh8uI2/86Fbu7933hkA/HweiCmP5QgF/8PecFM00gYvykxf0RZud8bg8zu+YfggDFUc1Kw=="
+ },
+ "@fortawesome/fontawesome-svg-core": {
+ "version": "1.2.24",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.24.tgz",
+ "integrity": "sha512-9uVGOEZwviZKbkOVX8nn8cErVqOHBAd1Fqd2OH7Iwu0vxGWdb3fFOMhaAyMXUHZpq1u5C9/HClCV49ci4WmJAg==",
+ "requires": {
+ "@fortawesome/fontawesome-common-types": "^0.2.24"
+ }
+ },
+ "@fortawesome/free-solid-svg-icons": {
+ "version": "5.11.1",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.11.1.tgz",
+ "integrity": "sha512-bB3hXON1K6mVOetTTg5VXZ4CAHg866p7MqenDkJ/eVcbWbGQRE45ojHEwkf37tWx3E8z6lcEameRwU9r5tGwjg==",
+ "requires": {
+ "@fortawesome/fontawesome-common-types": "^0.2.24"
+ }
+ },
+ "@fortawesome/vue-fontawesome": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-0.1.7.tgz",
+ "integrity": "sha512-YCw2Q2m4fxzyFsPOH3uDYMoJztTD+pT+AAyse4LFpbdrBg+r8ueaVT8BFnXEjrGwMDJJeXrwJ5AOC6q/JWBI4w=="
+ },
"@hapi/address": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.0.0.tgz",
@@ -8237,7 +8263,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -8258,12 +8285,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -8278,17 +8307,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -8405,7 +8437,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -8417,6 +8450,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -8431,6 +8465,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -8438,12 +8473,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -8462,6 +8499,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -8542,7 +8580,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -8554,6 +8593,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -8639,7 +8679,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -8675,6 +8716,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -8694,6 +8736,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -8737,12 +8780,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
}
}
},
@@ -16804,6 +16849,11 @@
"vue-template-es2015-compiler": "^1.6.0"
}
},
+ "vue-js-modal": {
+ "version": "1.3.31",
+ "resolved": "https://registry.npmjs.org/vue-js-modal/-/vue-js-modal-1.3.31.tgz",
+ "integrity": "sha512-gwt2904sWbMUuUcHwKQ510IEs4G7S3bqVWLYeTOc2eEyWMmmnT9UmojDsXIexFnPVM7cZTua37z3Jm/h0i0y8Q=="
+ },
"vue-loader": {
"version": "15.7.1",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.7.1.tgz",
diff --git a/package.json b/package.json
index 6123785..d85f3c1 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,9 @@
"deploy-staging": "sh ./scripts/staging-deploy.sh"
},
"dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^1.2.24",
+ "@fortawesome/free-solid-svg-icons": "^5.11.1",
+ "@fortawesome/vue-fontawesome": "^0.1.7",
"c3": "^0.7.1",
"core-js": "^2.6.5",
"crypto-js": "^3.1.9-1",
@@ -22,6 +25,7 @@
"serve-static": "^1.14.1",
"stylus": "^0.54.5",
"vue": "^2.6.10",
+ "vue-js-modal": "^1.3.31",
"vue-resource": "^1.5.1",
"vue-router": "^3.0.3",
"vuejs-datepicker": "^1.5.4",
diff --git a/src/components/data-table.vue b/src/components/data-table.vue
index 555496b..83b8d85 100644
--- a/src/components/data-table.vue
+++ b/src/components/data-table.vue
@@ -4,9 +4,18 @@
| {{ header }} |
+ Actions |
| {{ f(d) }} |
+
+
+
+ |
@@ -17,7 +26,7 @@ import Vue from 'vue';
export default Vue.extend({
name: 'data-table',
- props: ['title', 'data', 'headers', 'fields']
+ props: ['title', 'data', 'headers', 'fields', 'editAction', 'deleteAction']
});
@@ -35,6 +44,11 @@ table {
padding: 10px;
border-left: 1px solid black;
}
+ td, .actions {
+ a {
+ margin: 5px;
+ }
+ }
}
}
diff --git a/src/components/edit-version.vue b/src/components/edit-version.vue
new file mode 100644
index 0000000..ad62495
--- /dev/null
+++ b/src/components/edit-version.vue
@@ -0,0 +1,124 @@
+
+
+
+
Edit Version
+
+
+
+
+
+
+
+
+
diff --git a/src/main.ts b/src/main.ts
index faea95f..729b97f 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -4,9 +4,18 @@ import Cookie from 'js-cookie';
import App from './App.vue';
import router from './router';
import store from './store';
+import { library } from '@fortawesome/fontawesome-svg-core'
+import { faEdit, faTrash } from '@fortawesome/free-solid-svg-icons'
+import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
+import VModal from 'vue-js-modal'
+
+library.add(faEdit)
+library.add(faTrash)
+Vue.component('font-awesome-icon', FontAwesomeIcon)
Vue.config.productionTip = false;
+Vue.use(VModal)
Vue.use(VueResource);
Vue.http.interceptors.push((request: any) => {
diff --git a/src/router.ts b/src/router.ts
index fb6407c..8825260 100644
--- a/src/router.ts
+++ b/src/router.ts
@@ -34,7 +34,7 @@ const routes = [
},
{
name: 'batch-history',
- path: '/batch-history',
+ path: '/batch-history/:batchId?',
meta: { title: 'Brewhops - Batch History' },
component: () => import('@/views/batch-history.vue'),
},
diff --git a/src/views/batch-history.vue b/src/views/batch-history.vue
index c70b05d..1d41f40 100644
--- a/src/views/batch-history.vue
+++ b/src/views/batch-history.vue
@@ -1,6 +1,11 @@
+
+
Batch History
@@ -88,6 +93,8 @@
v => v.temperature,
v => v.pressure
]"
+ v-bind:editAction="version => (this.editableVersion = version)"
+ v-bind:deleteAction="this.deleteVersion"
/>
@@ -110,6 +117,7 @@ import { Moment } from 'moment';
import chart from '@/components/chart.vue';
import loader from '@/components/loader.vue';
import dataTable from '@/components/data-table.vue';
+import editVersion from '@/components/edit-version.vue';
import { orderBy } from 'natural-orderby';
interface IHistoryState {
@@ -129,11 +137,12 @@ interface IHistoryState {
pHData: any[];
abvData: any[];
tempData: any[];
+ editableVersion?: Version;
}
export default Vue.extend({
name: 'batch-history',
- components: { chart: chart, dataTable: dataTable, loader: loader },
+ components: { chart: chart, dataTable: dataTable, loader: loader, editVersion: editVersion },
data(): IHistoryState {
return {
batch_titles: ['Volume', 'Bright', 'Generation', 'Date Started', 'Date Completed'],
@@ -160,7 +169,8 @@ export default Vue.extend({
fermentationData: [],
pHData: [],
abvData: [],
- tempData: []
+ tempData: [],
+ editableVersion: undefined
};
},
async beforeMount() {
@@ -176,6 +186,11 @@ export default Vue.extend({
this.employees =
employees.data;
this.actions = actions.data;
this.batches = orderBy(response.data, (b: Batch) => b.name, 'desc');
+
+ if (this.$route.params.batchId) {
+ this.batch_id = parseInt(this.$route.params.batchId);
+ await this.batchChoose();
+ }
} catch (err) {
// tslint:disable-next-line:no-console
console.error(err);
@@ -185,6 +200,29 @@ export default Vue.extend({
home() {
router.push('/');
},
+ async editVersionCloseHook(version: Version) {
+ this.editableVersion = undefined;
+ if (version) {
+ try {
+ await this.$http.patch(`${process.env.VUE_APP_API}/versions/id/${version.id}`, version);
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ },
+ async deleteVersion(version: Version) {
+ const confirmation = confirm(
+ `Are you sure you want to delete the version from ${this.formatDate(version.measured_on)}?`
+ );
+ if (confirmation) {
+ try {
+ await this.$http.delete(`${process.env.VUE_APP_API}/versions/id/${version.id}`);
+ this.versions = this.versions.filter(v => v.id !== version.id);
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ },
getEmployeeName(employee: Employee) {
let name = 'N/A';
if (employee && employee.first_name && employee.last_name)
@@ -199,46 +237,53 @@ export default Vue.extend({
]
];
},
- formatDate(date: string | null) {
+ formatDate(date: string | Moment | undefined) {
return date ? moment(date).format('MM-DD-YYYY') : '';
},
async batchChoose() {
+ router.push(`/batch-history/${this.batch_id}`);
this.loading = true;
// filter out all the batches that aren't ours, and set that one element
// to our batch object
- this.batch = this.batches.filter(e => e.id === this.batch_id)[0];
+ const batch = this.batches.find(e => e.id === this.batch_id);
- // when the user chooses a batch, get the info on that batch
- const [versions, tasks, ...arr] = await Promise.all([
- (async () => {
- const batchResponse = await this.$http.get(
- `${process.env.VUE_APP_API}/versions/batch/${this.batch_id}/`
- );
+ if (batch === undefined) {
+ console.error(`Could not find selected batch by id: ${this.batch_id}`);
+ } else {
+ this.batch = batch;
- return (batchResponse.data as Version[])
- .map((v: Version) => {
- v.measured_on = moment(v.measured_on);
- return v;
- })
- .sort((a: Version, b: Version) => {
- return moment.utc(a.measured_on).diff(moment.utc(b.measured_on));
- });
- })(),
- (async () => {
- const taskResponse = await this.$http.get(
- `${process.env.VUE_APP_API}/tasks/batch/${this.batch_id}/`
- );
+ // when the user chooses a batch, get the info on that batch
+ const [versions, tasks, ...arr] = await Promise.all([
+ (async () => {
+ const batchResponse = await this.$http.get(
+ `${process.env.VUE_APP_API}/versions/batch/${this.batch_id}/`
+ );
- return (taskResponse.data as Task[]).map((t: Task) => {
- t.added_on = moment(t.added_on);
- return t;
- });
- })(),
- this.loadGraphData(this.batch.id, this.batch.recipe_id)
- ]);
+ return (batchResponse.data as Version[])
+ .map((v: Version) => {
+ v.measured_on = moment(v.measured_on);
+ return v;
+ })
+ .sort((a: Version, b: Version) => {
+ return moment.utc(a.measured_on).diff(moment.utc(b.measured_on));
+ });
+ })(),
+ (async () => {
+ const taskResponse = await this.$http.get(
+ `${process.env.VUE_APP_API}/tasks/batch/${this.batch_id}/`
+ );
- this.versions = versions;
- this.tasks = tasks;
+ return (taskResponse.data as Task[]).map((t: Task) => {
+ t.added_on = moment(t.added_on);
+ return t;
+ });
+ })(),
+ this.loadGraphData(this.batch_id, this.batch.recipe_id)
+ ]);
+
+ this.versions = versions;
+ this.tasks = tasks;
+ }
this.loading = false;
},