From 6b5bf7460b5d0215ec9bb57de785b3dc82c6bf43 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 16 Jun 2020 16:14:11 -0400 Subject: [PATCH 01/20] Rename un/archive actions to un/archiveSelected --- src/store/collection/modules/archive.ts | 4 ++-- src/store/collection/modules/inventory.ts | 4 ++-- src/views/Archive.vue | 4 ++-- src/views/Inventory.vue | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/store/collection/modules/archive.ts b/src/store/collection/modules/archive.ts index 7d795b6..3658bdc 100644 --- a/src/store/collection/modules/archive.ts +++ b/src/store/collection/modules/archive.ts @@ -5,14 +5,14 @@ import { unarchiveItem, deleteItem } from "@/network/archive-service"; import { CollectionState, mutation } from "../types"; export const actions: ActionTree = { - unarchiveItems({ commit, state }): void { + unarchiveSelected({ commit, state }): void { try { state.selected.forEach(async (item: Furniture) => { await unarchiveItem(item.id); }); commit(mutation.CLEAR_SELECTED); } catch (e) { - console.log("archiveItems error: ", e); + console.log("archiveSelected error: ", e); } }, deleteItems({ commit, state }): void { diff --git a/src/store/collection/modules/inventory.ts b/src/store/collection/modules/inventory.ts index bee19f7..8a0d93b 100644 --- a/src/store/collection/modules/inventory.ts +++ b/src/store/collection/modules/inventory.ts @@ -5,14 +5,14 @@ import { Furniture } from "@/data/Furniture"; import { CollectionState, mutation } from "../types"; export const actions: ActionTree = { - archiveItems({ commit, state }): void { + archiveSelected({ commit, state }): void { try { state.selected.forEach(async (item: Furniture) => { await archiveItem(item.id); }); commit(mutation.CLEAR_SELECTED); } catch (e) { - console.log("archiveItems error: ", e); + console.log("archiveSelected error: ", e); } }, async commitItem({ commit, state }): Promise { diff --git a/src/views/Archive.vue b/src/views/Archive.vue index 536f8c7..85572a4 100644 --- a/src/views/Archive.vue +++ b/src/views/Archive.vue @@ -9,7 +9,7 @@ :actions="actions" :disabled="selected.length < 1" @download="getSpreadsheet" - @unarchive="unarchiveItems()" + @unarchive="unarchiveSelected()" @delete="deleteItems()" /> @@ -56,7 +56,7 @@ const NAMESPACE = "archive"; }), methods: mapActions(NAMESPACE, [ "bindItems", - "unarchiveItems", + "unarchiveSelected", "deleteItems", ]), }) diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index f7a56df..d4c211e 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -20,7 +20,7 @@ :actions="actions" :disabled="selected.length < 1" @download="getSpreadsheet" - @archive="archiveItems()" + @archive="archiveSelected()" /> @@ -95,7 +95,7 @@ const NAMESPACE = "inventory"; action.CLEAR_UPDATES, action.CLEAR_CURRENT, action.COMMIT_UPDATES, - "archiveItems", + "archiveSelected", "commitItem", ]), }) From 6b349f278eb0339a60e91a2601c4dd0fed388e56 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 16 Jun 2020 20:59:35 -0400 Subject: [PATCH 02/20] Update edit card dialog behavior - show card when current is non-null - uses computed property --- src/components/EditCard.vue | 15 +++++++++------ src/views/Inventory.vue | 11 ++++++----- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/components/EditCard.vue b/src/components/EditCard.vue index 58efc44..1dfcecd 100644 --- a/src/components/EditCard.vue +++ b/src/components/EditCard.vue @@ -17,6 +17,8 @@ v-if="!isEdit" @close="$emit('close')" @edit="$emit('edit')" + @export="$emit('export')" + @archive="$emit('archive')" /> @@ -34,6 +36,7 @@

Donor Info

+ Promise; readonly setCurrent!: ({ item }: { item: Furniture }) => void; @@ -130,7 +131,9 @@ export default class Inventory extends Vue { isAdd = false; - editCard = false; + get editCard(): boolean { + return !!this.current; + } unsavedDialog = false; @@ -206,10 +209,9 @@ export default class Inventory extends Vue { closeDialog(forceClose = false): void { if (this.updatesLength === 0 || forceClose) { this.unsavedDialog = false; - this.editCard = false; this.isEdit = false; this.isAdd = false; - this.clearUpdates(); + this.clearCurrent(); } else { this.unsavedDialog = true; } @@ -230,7 +232,6 @@ export default class Inventory extends Vue { this.setCurrent({ item: new Furniture() }); this.isEdit = true; this.isAdd = true; - this.editCard = true; } /** From 47681459bd0c1e60c8cda5151a8f2a95b5e5b01e Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 16 Jun 2020 21:00:08 -0400 Subject: [PATCH 03/20] Add events for export and archive from edit card --- src/components/FurnitureCardDialog.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/FurnitureCardDialog.vue b/src/components/FurnitureCardDialog.vue index c525738..7179c11 100644 --- a/src/components/FurnitureCardDialog.vue +++ b/src/components/FurnitureCardDialog.vue @@ -14,6 +14,8 @@ @edit="$emit('edit')" @close="closeDialog()" @save="saveChanges()" + @export="$emit('export')" + @archive="$emit('archive')" /> From 7b798fb7ca723903283b8d4d131740ac31876f43 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jun 2020 12:05:57 -0400 Subject: [PATCH 04/20] Implement module actions for archiving current - also unarchive, delete - renamed deleteItems --> deleteSelected --- src/store/collection/modules/archive.ts | 22 +++++++++++++++++++--- src/store/collection/modules/inventory.ts | 12 ++++++++++-- src/views/Archive.vue | 4 ++-- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/store/collection/modules/archive.ts b/src/store/collection/modules/archive.ts index 3658bdc..99d3dbd 100644 --- a/src/store/collection/modules/archive.ts +++ b/src/store/collection/modules/archive.ts @@ -5,6 +5,14 @@ import { unarchiveItem, deleteItem } from "@/network/archive-service"; import { CollectionState, mutation } from "../types"; export const actions: ActionTree = { + async unarchiveCurrent({ commit, state }): Promise { + try { + await unarchiveItem(state.current!.id); + commit(mutation.CLEAR_CURRENT); + } catch (e) { + console.error("unarchiveCurrent error:", e); + } + }, unarchiveSelected({ commit, state }): void { try { state.selected.forEach(async (item: Furniture) => { @@ -12,17 +20,25 @@ export const actions: ActionTree = { }); commit(mutation.CLEAR_SELECTED); } catch (e) { - console.log("archiveSelected error: ", e); + console.error("unarchiveSelected error:", e); + } + }, + async deleteCurrent({ commit, state }): Promise { + try { + await deleteItem(state.current!.id); + commit(mutation.CLEAR_CURRENT); + } catch (e) { + console.error("deleteCurrent error:", e); } }, - deleteItems({ commit, state }): void { + deleteSelected({ commit, state }): void { try { state.selected.forEach(async (item: Furniture) => { await deleteItem(item.id); }); commit(mutation.CLEAR_SELECTED); } catch (e) { - console.log("deleteItems error: ", e); + console.error("deleteSelected error:", e); } }, }; diff --git a/src/store/collection/modules/inventory.ts b/src/store/collection/modules/inventory.ts index 8a0d93b..9903b8a 100644 --- a/src/store/collection/modules/inventory.ts +++ b/src/store/collection/modules/inventory.ts @@ -5,6 +5,14 @@ import { Furniture } from "@/data/Furniture"; import { CollectionState, mutation } from "../types"; export const actions: ActionTree = { + async archiveCurrent({ commit, state }): Promise { + try { + await archiveItem(state.current!.id); + commit(mutation.CLEAR_CURRENT); + } catch (e) { + console.error("archiveCurrent error:", e); + } + }, archiveSelected({ commit, state }): void { try { state.selected.forEach(async (item: Furniture) => { @@ -12,7 +20,7 @@ export const actions: ActionTree = { }); commit(mutation.CLEAR_SELECTED); } catch (e) { - console.log("archiveSelected error: ", e); + console.error("archiveSelected error:", e); } }, async commitItem({ commit, state }): Promise { @@ -22,7 +30,7 @@ export const actions: ActionTree = { await addItem(state.current!); commit(mutation.CLEAR_UPDATES); } catch (e) { - console.log("addItem error: ", e); + console.error("addItem error:", e); } }, }; diff --git a/src/views/Archive.vue b/src/views/Archive.vue index 85572a4..212ba29 100644 --- a/src/views/Archive.vue +++ b/src/views/Archive.vue @@ -10,7 +10,7 @@ :disabled="selected.length < 1" @download="getSpreadsheet" @unarchive="unarchiveSelected()" - @delete="deleteItems()" + @delete="deleteSelected()" /> @@ -57,7 +57,7 @@ const NAMESPACE = "archive"; methods: mapActions(NAMESPACE, [ "bindItems", "unarchiveSelected", - "deleteItems", + "deleteSelected", ]), }) export default class Inventory extends Vue { From f1fc6fca96e7281213374143d5366b8e6be498e0 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jun 2020 13:54:04 -0400 Subject: [PATCH 05/20] Rename category to collection in XLSX function --- functions/src/index.ts | 10 +++++----- src/views/Archive.vue | 2 +- src/views/Inventory.vue | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/functions/src/index.ts b/functions/src/index.ts index 540739d..0d98d6f 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -108,9 +108,9 @@ function renameSubheaders(mainHeaders: string[], subheaders: string[]): any { return newHeaders; } -async function getData(id: string[], category: string): Promise { +async function getData(id: string[], collection: string): Promise { const inventory: any = []; - const furniture = admin.firestore().collection(category); + const furniture = admin.firestore().collection(collection); const wb = XLSX.utils.book_new(); // converting each inventory entry to single-layer JSON object @@ -178,14 +178,14 @@ async function getData(id: string[], category: string): Promise { const date = `${today.getFullYear()}-${ today.getMonth() + 1 }-${today.getDate()}`; - const fileName = category.concat(`${date}.xlsx`); + const fileName = collection.concat(`${date}.xlsx`); const file = bucket.file(fileName); await file.save(buffer); return `/n2n-inventory/${fileName}`; } exports.getInventoryXLSX = functions.https.onCall( - (data: { id: string[]; category: string }) => { - return getData(data.id, data.category); + (data: { id: string[]; collection: string }) => { + return getData(data.id, data.collection); }, ); diff --git a/src/views/Archive.vue b/src/views/Archive.vue index 212ba29..b329625 100644 --- a/src/views/Archive.vue +++ b/src/views/Archive.vue @@ -108,7 +108,7 @@ export default class Inventory extends Vue { const idArray = this.selected.map((value) => value.id); // Uncomment if running `npm run shell` for backend functions: // firebase.functions().useFunctionsEmulator("http://localhost:5001"); - getInventoryXLSX({ id: idArray, category: "archive" }) + getInventoryXLSX({ id: idArray, collection: collections.ARCHIVE }) .then((res) => { const storage = firebase.storage(); const gsref = storage.refFromURL(`gs:/${res.data}`); diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 059cd5b..0f3cabb 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -176,7 +176,7 @@ export default class Inventory extends Vue { const idArray = this.selected.map((value) => value.id); // Uncomment if running `npm run shell` for backend functions: // firebase.functions().useFunctionsEmulator("http://localhost:5001"); - getInventoryXLSX({ id: idArray, category: "furniture" }) + getInventoryXLSX({ id: idArray, collection: collections.INVENTORY }) .then((res) => { const storage = firebase.storage(); const gsref = storage.refFromURL(`gs:/${res.data}`); From e4f9424917af16e31f7cf3eca30d6b2747f5c276 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jun 2020 14:23:30 -0400 Subject: [PATCH 06/20] Add exports for other Firebase services --- src/network/archive-service.ts | 2 +- src/network/db.ts | 10 +++++++++- src/network/inventory-service.ts | 2 +- src/store/collection/actions.ts | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/network/archive-service.ts b/src/network/archive-service.ts index 2b32e0b..ff0bd4b 100644 --- a/src/network/archive-service.ts +++ b/src/network/archive-service.ts @@ -1,7 +1,7 @@ import { Furniture } from "@/data/Furniture"; import collections from "./collections"; import FirestoreService from "./firestore-service"; -import db from "./db"; +import { db } from "./db"; class ArchiveService extends FirestoreService { unarchiveItem = async (id: string): Promise => { diff --git a/src/network/db.ts b/src/network/db.ts index 75aa716..ad1ccbf 100644 --- a/src/network/db.ts +++ b/src/network/db.ts @@ -1,7 +1,15 @@ import firebase from "firebase/app"; import "firebase/firestore"; +import "firebase/functions"; +import "firebase/storage"; import config from "./config"; -const db = firebase.initializeApp(config).firestore(); +firebase.initializeApp(config); + +export const db = firebase.firestore(); + +export const functions = firebase.functions(); + +export const storage = firebase.storage(); export default db; diff --git a/src/network/inventory-service.ts b/src/network/inventory-service.ts index cb426b3..2d0c539 100644 --- a/src/network/inventory-service.ts +++ b/src/network/inventory-service.ts @@ -1,7 +1,7 @@ import { Furniture } from "@/data/Furniture"; import collections from "./collections"; import FirestoreService from "./firestore-service"; -import db from "./db"; +import { db } from "./db"; class InventoryService extends FirestoreService { archiveItem = async (id: string): Promise => { diff --git a/src/store/collection/actions.ts b/src/store/collection/actions.ts index 5e50b88..17979fd 100644 --- a/src/store/collection/actions.ts +++ b/src/store/collection/actions.ts @@ -1,5 +1,5 @@ import { firestoreAction } from "vuexfire"; -import db from "@/network/db"; +import { db } from "@/network/db"; import FirestoreService from "@/network/firestore-service"; import collections from "@/network/collections"; import { Furniture } from "@/data/Furniture"; From 4e592e6a1ac10c2715ec62b331efa8b7f185df1b Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jun 2020 14:24:21 -0400 Subject: [PATCH 07/20] Add exportItems to FirestoreService --- src/network/firestore-service.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/network/firestore-service.ts b/src/network/firestore-service.ts index f0dea6d..c92c481 100644 --- a/src/network/firestore-service.ts +++ b/src/network/firestore-service.ts @@ -1,5 +1,5 @@ import { Furniture } from "@/data/Furniture"; -import db from "./db"; +import { db, functions, storage } from "./db"; import collections from "./collections"; import { deepCopy } from "./converters"; @@ -43,4 +43,20 @@ export default class FirestoreService { deleteItem = (id: string): Promise => { return db.collection(this.collection).doc(id).delete(); }; + + exportItems = (ids: string[]): Promise => { + const getInventoryXLSX = functions.httpsCallable("getInventoryXLSX"); + // Uncomment if running `npm run shell` for backend functions: + // firebase.functions().useFunctionsEmulator("http://localhost:5001"); + return getInventoryXLSX({ id: ids, collection: this.collection }) + .then((res) => { + const gsref = storage.refFromURL(`gs:/${res.data}`); + gsref.getDownloadURL().then((url) => { + window.open(url); + }); + }) + .catch((err) => { + console.error("exportItem error:", err); + }); + }; } From 2fd18e893ba39d75e344adc7537f46b6983c4905 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jun 2020 14:26:03 -0400 Subject: [PATCH 08/20] Rename db to firebase - firebase contains db, functions, storage --- src/network/archive-service.ts | 2 +- src/network/{db.ts => firebase.ts} | 0 src/network/firestore-service.ts | 2 +- src/network/inventory-service.ts | 2 +- src/store/collection/actions.ts | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename src/network/{db.ts => firebase.ts} (100%) diff --git a/src/network/archive-service.ts b/src/network/archive-service.ts index ff0bd4b..a52e7e0 100644 --- a/src/network/archive-service.ts +++ b/src/network/archive-service.ts @@ -1,7 +1,7 @@ import { Furniture } from "@/data/Furniture"; import collections from "./collections"; import FirestoreService from "./firestore-service"; -import { db } from "./db"; +import { db } from "./firebase"; class ArchiveService extends FirestoreService { unarchiveItem = async (id: string): Promise => { diff --git a/src/network/db.ts b/src/network/firebase.ts similarity index 100% rename from src/network/db.ts rename to src/network/firebase.ts diff --git a/src/network/firestore-service.ts b/src/network/firestore-service.ts index c92c481..3659dd0 100644 --- a/src/network/firestore-service.ts +++ b/src/network/firestore-service.ts @@ -1,5 +1,5 @@ import { Furniture } from "@/data/Furniture"; -import { db, functions, storage } from "./db"; +import { db, functions, storage } from "./firebase"; import collections from "./collections"; import { deepCopy } from "./converters"; diff --git a/src/network/inventory-service.ts b/src/network/inventory-service.ts index 2d0c539..5513da8 100644 --- a/src/network/inventory-service.ts +++ b/src/network/inventory-service.ts @@ -1,7 +1,7 @@ import { Furniture } from "@/data/Furniture"; import collections from "./collections"; import FirestoreService from "./firestore-service"; -import { db } from "./db"; +import { db } from "./firebase"; class InventoryService extends FirestoreService { archiveItem = async (id: string): Promise => { diff --git a/src/store/collection/actions.ts b/src/store/collection/actions.ts index 17979fd..3d03b64 100644 --- a/src/store/collection/actions.ts +++ b/src/store/collection/actions.ts @@ -1,5 +1,5 @@ import { firestoreAction } from "vuexfire"; -import { db } from "@/network/db"; +import { db } from "@/network/firebase"; import FirestoreService from "@/network/firestore-service"; import collections from "@/network/collections"; import { Furniture } from "@/data/Furniture"; From 021b06c713e8168bbc3c5f06db3d53c9cb609b7b Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jun 2020 15:46:21 -0400 Subject: [PATCH 09/20] Implement actions for export current and selected --- src/store/collection/actions.ts | 19 ++++++++++++++++++- src/store/collection/types.ts | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/store/collection/actions.ts b/src/store/collection/actions.ts index 3d03b64..ac86f2f 100644 --- a/src/store/collection/actions.ts +++ b/src/store/collection/actions.ts @@ -15,6 +15,14 @@ const actions: ActionTree = { commit(mutation.CLEAR_UPDATES); commit(mutation.CLEAR_CURRENT); }, + async [action.EXPORT_CURRENT]({ state }): Promise { + try { + const service = new FirestoreService(state.collection!); + await service.exportItems([state.current!.id]); + } catch (e) { + console.error("exportCurrent error:", e); + } + }, [action.UPDATE_CURRENT]( { commit }, { updates }: { updates: Partial }, @@ -29,13 +37,14 @@ const actions: ActionTree = { { collection }: { collection: collections }, ): Promise { try { + // TODO: just use state.collection const service = new FirestoreService(collection); commit(mutation.UPDATE_CURRENT, { updates: state.currentUpdates }); commit(mutation.CLEAN_CURRENT); await service.updateItem(state.current!.id, state.currentUpdates); commit(mutation.CLEAR_UPDATES); } catch (e) { - console.log("commitUpdates error: ", e); + console.error("commitUpdates error:", e); } }, [action.SET_SELECTED]({ commit }, { list }: { list: Furniture[] }): void { @@ -47,6 +56,14 @@ const actions: ActionTree = { [action.ADD_SELECTED]({ commit }, { item }: { item: Furniture }): void { commit(mutation.ADD_SELECTED, { item }); }, + async [action.EXPORT_SELECTED]({ state }): Promise { + try { + const service = new FirestoreService(state.collection!); + await service.exportItems(state.selected.map((item) => item.id)); + } catch (e) { + console.error("exportSelected error:", e); + } + }, [action.BIND_ITEMS]: firestoreAction( ({ bindFirestoreRef, state }) => { return bindFirestoreRef("items", db.collection(state.collection!)); diff --git a/src/store/collection/types.ts b/src/store/collection/types.ts index b223fc6..0d4ced6 100644 --- a/src/store/collection/types.ts +++ b/src/store/collection/types.ts @@ -36,10 +36,12 @@ export enum action { SET_CURRENT = "setCurrent", CLEAR_CURRENT = "clearCurrent", UPDATE_CURRENT = "updateCurrent", + EXPORT_CURRENT = "exportCurrent", CLEAR_UPDATES = "clearUpdates", COMMIT_UPDATES = "commitUpdates", SET_SELECTED = "setSelected", CLEAR_SELECTED = "clearSelected", + EXPORT_SELECTED = "exportSelected", ADD_SELECTED = "addSelected", BIND_ITEMS = "bindItems", UNBIND_ITEMS = "unbindItems", From 6c02b016ad430addcaf44f363893fe1c4c5667f4 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jun 2020 15:49:48 -0400 Subject: [PATCH 10/20] Update inventory to use new export actions --- src/views/Inventory.vue | 44 +++++++++++------------------------------ 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/src/views/Inventory.vue b/src/views/Inventory.vue index 0f3cabb..447eb02 100644 --- a/src/views/Inventory.vue +++ b/src/views/Inventory.vue @@ -55,10 +55,6 @@ import Vue from "vue"; import { mapActions, mapGetters } from "vuex"; import Component from "vue-class-component"; -import * as firebase from "firebase/app"; -import "firebase/firestore"; -import "firebase/functions"; -import "firebase/storage"; // network, data import collections from "@/network/collections"; import { Furniture } from "@/data/Furniture"; @@ -94,6 +90,7 @@ const NAMESPACE = "inventory"; action.CLEAR_UPDATES, action.CLEAR_CURRENT, action.COMMIT_UPDATES, + action.EXPORT_SELECTED, "archiveSelected", "commitItem", ]), @@ -104,23 +101,25 @@ export default class Inventory extends Vue { /** Vuex map helper properties */ readonly current!: Furniture; - readonly bindItems!: () => Promise; + readonly selected!: Furniture[]; - readonly setCurrent!: ({ item }: { item: Furniture }) => void; + readonly [action.BIND_ITEMS]!: () => Promise; - readonly selected!: Furniture[]; + readonly [action.SET_CURRENT]!: ({ item }: { item: Furniture }) => void; + + readonly [action.EXPORT_SELECTED]!: () => Promise; /* eslint-disable object-curly-newline */ - readonly commitUpdates!: ({ + readonly [action.COMMIT_UPDATES]!: ({ collection, }: { collection: collections; }) => void; /* eslint-enable object-curly-newline */ - readonly clearCurrent!: () => void; + readonly [action.CLEAR_CURRENT]!: () => void; - readonly clearUpdates!: () => void; + readonly [action.CLEAR_UPDATES]!: () => void; readonly updatesLength!: number; @@ -167,29 +166,10 @@ export default class Inventory extends Vue { this.bindItems(); } - getSpreadsheet(): void { - // TODO: maybe abstract this to the firestore-service + async getSpreadsheet(): Promise { this.downloading = true; - const getInventoryXLSX = firebase - .functions() - .httpsCallable("getInventoryXLSX"); - const idArray = this.selected.map((value) => value.id); - // Uncomment if running `npm run shell` for backend functions: - // firebase.functions().useFunctionsEmulator("http://localhost:5001"); - getInventoryXLSX({ id: idArray, collection: collections.INVENTORY }) - .then((res) => { - const storage = firebase.storage(); - const gsref = storage.refFromURL(`gs:/${res.data}`); - gsref.getDownloadURL().then((url) => { - window.open(url); - }); - this.downloading = false; - }) - .catch((err) => { - console.log(err); - console.log(this.selected.length); // workaround not using this - this.downloading = false; - }); + await this.exportSelected(); + this.downloading = false; } /** From b18852bfc99c1cc2a47f33c64d686fc62e29b146 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jun 2020 21:30:14 -0400 Subject: [PATCH 11/20] Remove collection parameter from commitUpdates - uses state.collection now --- src/store/collection/actions.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/store/collection/actions.ts b/src/store/collection/actions.ts index ac86f2f..6640f49 100644 --- a/src/store/collection/actions.ts +++ b/src/store/collection/actions.ts @@ -1,7 +1,6 @@ import { firestoreAction } from "vuexfire"; import { db } from "@/network/firebase"; import FirestoreService from "@/network/firestore-service"; -import collections from "@/network/collections"; import { Furniture } from "@/data/Furniture"; import { ActionTree } from "vuex"; import { CollectionState, mutation, action } from "./types"; @@ -32,13 +31,9 @@ const actions: ActionTree = { [action.CLEAR_UPDATES]({ commit }): void { commit(mutation.CLEAR_UPDATES); }, - async [action.COMMIT_UPDATES]( - { commit, state }, - { collection }: { collection: collections }, - ): Promise { + async [action.COMMIT_UPDATES]({ commit, state }): Promise { try { - // TODO: just use state.collection - const service = new FirestoreService(collection); + const service = new FirestoreService(state.collection!); commit(mutation.UPDATE_CURRENT, { updates: state.currentUpdates }); commit(mutation.CLEAN_CURRENT); await service.updateItem(state.current!.id, state.currentUpdates); From f7adaf186891dbed565edbbe80a786eb590f5581 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jun 2020 21:32:11 -0400 Subject: [PATCH 12/20] Move all dialog logic into FurnitureCardDialog - now contains the UnsavedDialog - handles closing, saving, toggling edit --- src/components/FurnitureCardDialog.vue | 112 +++++++++++++++++++------ src/views/Inventory.vue | 70 +--------------- 2 files changed, 87 insertions(+), 95 deletions(-) diff --git a/src/components/FurnitureCardDialog.vue b/src/components/FurnitureCardDialog.vue index 7179c11..c20bfa2 100644 --- a/src/components/FurnitureCardDialog.vue +++ b/src/components/FurnitureCardDialog.vue @@ -1,37 +1,66 @@ From d11628bbc323931a65a8527ee48ae69d75d39287 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jun 2020 21:32:39 -0400 Subject: [PATCH 13/20] Add dialogs back to Archive - uses new furniture card dialog --- src/views/Archive.vue | 54 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/views/Archive.vue b/src/views/Archive.vue index b329625..7592f08 100644 --- a/src/views/Archive.vue +++ b/src/views/Archive.vue @@ -21,6 +21,12 @@ :downloading="downloading" :collection="COLLECTION" /> + + @@ -28,18 +34,16 @@ import Vue from "vue"; import { mapActions, mapGetters } from "vuex"; import Component from "vue-class-component"; -import * as firebase from "firebase/app"; -import "firebase/firestore"; -import "firebase/functions"; -import "firebase/storage"; // data import { Furniture } from "@/data/Furniture"; import ViewAction from "@/data/ViewAction"; import collections from "@/network/collections"; +import { action } from "@/store/collection/types"; // components import FurnitureTable from "@/components/FurnitureTable.vue"; import FurnitureTableHeader from "@/components/FurnitureTableHeader.vue"; import ViewActionGroup from "@/components/ViewActionGroup.vue"; +import FurnitureCardDialog from "@/components/FurnitureCardDialog.vue"; const NAMESPACE = "archive"; @@ -48,6 +52,7 @@ const NAMESPACE = "archive"; FurnitureTable, FurnitureTableHeader, ViewActionGroup, + FurnitureCardDialog, }, computed: mapGetters(NAMESPACE, { archive: "getItems", @@ -55,7 +60,9 @@ const NAMESPACE = "archive"; selected: "getSelected", }), methods: mapActions(NAMESPACE, [ - "bindItems", + action.BIND_ITEMS, + action.EXPORT_SELECTED, + action.COMMIT_UPDATES, "unarchiveSelected", "deleteSelected", ]), @@ -63,6 +70,12 @@ const NAMESPACE = "archive"; export default class Inventory extends Vue { readonly COLLECTION = collections.ARCHIVE; + readonly current!: Furniture; + + readonly [action.BIND_ITEMS]!: () => Promise; + + readonly [action.EXPORT_SELECTED]!: () => Promise; + get actions(): ViewAction[] { return [ { @@ -84,9 +97,12 @@ export default class Inventory extends Vue { ]; } - bindItems!: () => Promise; + /** Furniture card dialog */ + isEdit = false; - selected!: Furniture[]; + get editCard(): boolean { + return !!this.current; + } downloading = false; @@ -100,28 +116,10 @@ export default class Inventory extends Vue { this.bindItems(); } - getSpreadsheet(): void { + async getSpreadsheet(): Promise { this.downloading = true; - const getInventoryXLSX = firebase - .functions() - .httpsCallable("getInventoryXLSX"); - const idArray = this.selected.map((value) => value.id); - // Uncomment if running `npm run shell` for backend functions: - // firebase.functions().useFunctionsEmulator("http://localhost:5001"); - getInventoryXLSX({ id: idArray, collection: collections.ARCHIVE }) - .then((res) => { - const storage = firebase.storage(); - const gsref = storage.refFromURL(`gs:/${res.data}`); - gsref.getDownloadURL().then((url) => { - window.open(url); - }); - this.downloading = false; - }) - .catch((err) => { - console.log(err); - console.log(this.selected.length); // workaround not using this - this.downloading = false; - }); + await this.exportSelected(); + this.downloading = false; } } From 8b4cb885e9cff21583d338a70739b6195fef84da Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 19 Jun 2020 00:54:28 -0400 Subject: [PATCH 14/20] Add loading to menu actions in ViewActionGroup --- src/components/ViewActionGroup.vue | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/ViewActionGroup.vue b/src/components/ViewActionGroup.vue index 4b92c18..ec2e0fd 100644 --- a/src/components/ViewActionGroup.vue +++ b/src/components/ViewActionGroup.vue @@ -6,8 +6,15 @@ @@ -76,7 +80,9 @@ const NAMESPACE = "inventory"; action.SET_CURRENT, action.CLEAR_CURRENT, action.EXPORT_SELECTED, + action.EXPORT_CURRENT, "archiveSelected", + "archiveCurrent", "commitItem", ]), }) @@ -94,8 +100,12 @@ export default class Inventory extends Vue { readonly [action.CLEAR_CURRENT]!: () => void; + readonly [action.EXPORT_CURRENT]!: () => Promise; + readonly commitItem!: () => Promise; + readonly archiveCurrent!: () => Promise; + /** Furniture card dialog */ isAdd = false; @@ -108,7 +118,7 @@ export default class Inventory extends Vue { downloading = false; - get actions(): ViewAction[] { + get inventoryActions(): ViewAction[] { return [ { icon: "archive", desc: "Archive selected items", emit: "archive" }, { @@ -125,6 +135,17 @@ export default class Inventory extends Vue { ]; } + menuLoading = false; + + readonly menuActions: ViewAction[] = [ + { icon: "archive", desc: "Archive", emit: "archive" }, + { + icon: "cloud_download", + desc: "Export", + emit: "export", + }, + ]; + /** * Called when component is mounted (lifecycle hook); binds inventory in * store to Firebase. @@ -155,5 +176,18 @@ export default class Inventory extends Vue { this.isAdd = false; this.clearCurrent(); } + + async commitArchive(): Promise { + this.menuLoading = true; + await this.archiveCurrent(); + this.menuLoading = false; + this.clearCurrent(); + } + + async commitExport(): Promise { + this.menuLoading = true; + await this.exportCurrent(); + this.menuLoading = false; + } } From aebf20134fdf8540a57b05d273ba591105725d9d Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 25 Jun 2020 13:54:30 -0400 Subject: [PATCH 18/20] Update functions to use Node 10 --- functions/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/package.json b/functions/package.json index 52dd430..01dbb69 100644 --- a/functions/package.json +++ b/functions/package.json @@ -10,7 +10,7 @@ "logs": "firebase functions:log" }, "engines": { - "node": "8" + "node": "10" }, "main": "lib/index.js", "dependencies": { From 97659919996d0395da748d28c2fbfcc9770af8ac Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 30 Jun 2020 14:59:34 -0400 Subject: [PATCH 19/20] Fix whitespace --- src/views/Archive.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/Archive.vue b/src/views/Archive.vue index 15a33a9..e661699 100644 --- a/src/views/Archive.vue +++ b/src/views/Archive.vue @@ -135,7 +135,7 @@ export default class Inventory extends Vue { } menuLoading = false; - + /** Filters */ datesFilter = [] as string[]; From e0531a8723765547b93cea42b33857d746c73084 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 30 Jun 2020 15:03:49 -0400 Subject: [PATCH 20/20] Fix bug that shows unsaved dialog after save - happened if you closed to quickly after an edit - made things async/await - added loading --- src/components/EditCard.vue | 12 ++++++++++++ src/components/FurnitureCardDialog.vue | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/components/EditCard.vue b/src/components/EditCard.vue index 04f7cea..5674441 100644 --- a/src/components/EditCard.vue +++ b/src/components/EditCard.vue @@ -1,5 +1,14 @@