Mercurial > gemma
comparison client/src/components/importoverview/ImportOverview.vue @ 2651:9f3856337f55
import_overview: new unified interface as default
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Thu, 14 Mar 2019 14:53:17 +0100 |
parents | client/src/components/importoverview/ImportOverviewAlt.vue@6c1730fc3dc1 |
children | 3c04c8e46bd4 |
comparison
equal
deleted
inserted
replaced
2650:a308baa7e7af | 2651:9f3856337f55 |
---|---|
2 <div class="overview"> | 2 <div class="overview"> |
3 <UIBoxHeader | 3 <UIBoxHeader |
4 icon="clipboard-check" | 4 icon="clipboard-check" |
5 title="Staging Area" | 5 title="Staging Area" |
6 :closeCallback="$parent.close" | 6 :closeCallback="$parent.close" |
7 :actions="[{ callback: loadLogs, icon: 'redo' }]" | |
7 /> | 8 /> |
8 <div class="d-flex flex-row w-100 justify-content-end"> | 9 <div class="position-relative"> |
9 <button | 10 <transition name="fade"> |
10 class="btn btn-sm btn-outline-info align-self-start mr-3" | 11 <div |
11 @click="refresh" | 12 class="loading d-flex justify-content-center align-items-center" |
12 > | 13 v-if="loading" |
13 <font-awesome-icon icon="redo"></font-awesome-icon> | |
14 </button> | |
15 </div> | |
16 <div class="d-flex flex-row w-100 border-bottom"> | |
17 <font-awesome-icon | |
18 class="pointer" | |
19 @click="toggleStaging()" | |
20 v-if="stagingVisible && staging.length > 0" | |
21 icon="angle-up" | |
22 fixed-width | |
23 ></font-awesome-icon> | |
24 <font-awesome-icon | |
25 class="pointer" | |
26 @click="toggleStaging()" | |
27 v-if="!stagingVisible && staging.length > 0" | |
28 icon="angle-down" | |
29 fixed-width | |
30 ></font-awesome-icon> | |
31 <span style="width:1.25em;" v-if="!(staging.length > 0)"></span> | |
32 <Staging v-if="stagingVisible && staging.length > 0"></Staging> | |
33 <div v-else class="d-flex flex-row"> | |
34 <h6> | |
35 <small><translate>Review</translate></small> | |
36 </h6> | |
37 <small class="ml-3" v-if="!(staging.length > 0)" | |
38 ><translate>Nothing to review</translate></small | |
39 > | 14 > |
40 </div> | 15 <font-awesome-icon icon="spinner" spin /> |
41 </div> | 16 </div> |
42 <div class="mt-2"> | 17 </transition> |
43 <div class="d-flex flex-row"> | 18 <div class="p-2 d-flex flex-row flex-fill justify-content-between"> |
44 <font-awesome-icon | 19 <Filters></Filters> |
45 class="pointer" | 20 <div> |
46 @click="toggleLogs()" | 21 <button |
47 v-if="logsVisible" | 22 class="btn btn-sm btn-info" |
48 icon="angle-up" | 23 :disabled="!reviewed.length" |
49 fixed-width | 24 @click="save" |
50 ></font-awesome-icon> | 25 > |
51 <font-awesome-icon | 26 <translate>Commit</translate> {{ reviewed.length }} |
52 class="pointer" | 27 </button> |
53 @click="toggleLogs()" | |
54 v-if="!logsVisible" | |
55 icon="angle-down" | |
56 fixed-width | |
57 ></font-awesome-icon> | |
58 <Logs v-if="logsVisible" :reload="reload"></Logs> | |
59 <div v-else> | |
60 <h6> | |
61 <small><translate>Logs</translate></small> | |
62 </h6> | |
63 </div> | 28 </div> |
64 </div> | 29 </div> |
30 <LogEntry | |
31 class="border-top d-flex-flex-column w-100" | |
32 :entry="entry" | |
33 v-for="entry in imports" | |
34 :key="entry.id" | |
35 ></LogEntry> | |
65 </div> | 36 </div> |
66 </div> | 37 </div> |
67 </template> | 38 </template> |
39 | |
40 <style lang="sass" scoped> | |
41 .loading | |
42 background: rgba(255, 255, 255, 0.9) | |
43 position: absolute | |
44 z-index: 99 | |
45 top: 0 | |
46 right: 0 | |
47 bottom: 0 | |
48 left: 0 | |
49 </style> | |
68 | 50 |
69 <script> | 51 <script> |
70 /* This is Free Software under GNU Affero General Public License v >= 3.0 | 52 /* This is Free Software under GNU Affero General Public License v >= 3.0 |
71 * without warranty, see README.md and license for details. | 53 * without warranty, see README.md and license for details. |
72 * | 54 * |
78 * Software engineering by Intevation GmbH | 60 * Software engineering by Intevation GmbH |
79 * | 61 * |
80 * Author(s): | 62 * Author(s): |
81 * Thomas Junk <thomas.junk@intevation.de> | 63 * Thomas Junk <thomas.junk@intevation.de> |
82 */ | 64 */ |
83 import { displayError } from "@/lib/errors.js"; | 65 |
84 import { mapState } from "vuex"; | 66 import { mapState } from "vuex"; |
67 import { displayError, displayInfo } from "@/lib/errors.js"; | |
68 import { STATES } from "@/store/imports.js"; | |
85 | 69 |
86 export default { | 70 export default { |
87 name: "importoverview", | 71 name: "importoverviewalt", |
72 components: { | |
73 Filters: () => import("./Filters.vue"), | |
74 LogEntry: () => import("./LogEntry.vue") | |
75 }, | |
88 data() { | 76 data() { |
89 return { | 77 return { |
90 reload: false | 78 loading: false |
91 }; | 79 }; |
92 }, | 80 }, |
93 components: { | |
94 Staging: () => import("./staging/Staging.vue"), | |
95 Logs: () => import("./importlogs/Logs.vue") | |
96 }, | |
97 computed: { | 81 computed: { |
98 ...mapState("imports", ["stagingVisible", "logsVisible", "staging"]) | 82 ...mapState("imports", ["imports", "filters", "reviewed"]) |
99 }, | 83 }, |
100 methods: { | 84 methods: { |
101 toggleStaging() { | |
102 this.$store.commit("imports/setStagingVisibility", !this.stagingVisible); | |
103 }, | |
104 toggleLogs() { | |
105 this.$store.commit("imports/setLogsVisibility", !this.logsVisible); | |
106 }, | |
107 refresh() { | |
108 this.reload = true; | |
109 this.loadImportQueue(); | |
110 this.loadLogs(); | |
111 }, | |
112 loadImportQueue() { | |
113 this.$store | |
114 .dispatch("imports/getStaging") | |
115 .then(() => { | |
116 this.reload = false; | |
117 }) | |
118 .catch(error => { | |
119 const { status, data } = error.response; | |
120 displayError({ | |
121 title: "Backend Error", | |
122 message: `${status}: ${data.message || data}` | |
123 }); | |
124 }); | |
125 }, | |
126 loadLogs() { | 85 loadLogs() { |
86 this.loading = true; | |
127 this.$store | 87 this.$store |
128 .dispatch("imports/getImports") | 88 .dispatch("imports/getImports") |
129 .then(() => { | 89 .then(() => { |
130 this.reload = false; | 90 this.loading = false; |
131 }) | 91 }) |
132 .catch(error => { | 92 .catch(error => { |
133 const { status, data } = error.response; | 93 const { status, data } = error.response; |
134 displayError({ | 94 displayError({ |
135 title: this.$gettext("Backend Error"), | 95 title: this.$gettext("Backend Error"), |
136 message: `${status}: ${data.message || data}` | 96 message: `${status}: ${data.message || data}` |
137 }); | 97 }); |
138 }); | 98 }); |
99 }, | |
100 save() { | |
101 if (!this.reviewed.length) return; | |
102 | |
103 let popupContent = `<table class="table table-sm small mb-0 border-0" style="margin-top: -1px;">`; | |
104 this.reviewed.forEach(r => { | |
105 let imp = this.imports.find(i => i.id === r.id); | |
106 let approved = STATES.APPROVED === r.status; | |
107 popupContent += `<tr> | |
108 <td>${imp.id}</td> | |
109 <td>${imp.kind.toUpperCase()}</td> | |
110 <td>${this.$options.filters.dateTime(imp.enqueued)}</td> | |
111 <td class="text-${approved ? "success" : "danger"}"> | |
112 ${this.$gettext(approved ? "approved" : "declined")} | |
113 </td> | |
114 </tr>`; | |
115 }); | |
116 popupContent += "</table>"; | |
117 | |
118 this.$store.commit("application/popup", { | |
119 icon: "clipboard-check", | |
120 title: this.$gettext("Finish Review"), | |
121 padding: false, | |
122 big: true, | |
123 content: popupContent, | |
124 confirm: { | |
125 icon: "check", | |
126 callback: () => { | |
127 let data = this.reviewed.map(r => ({ | |
128 id: r.id, | |
129 state: r.status | |
130 })); | |
131 this.$store | |
132 .dispatch("imports/confirmReview", data) | |
133 .then(response => { | |
134 this.loadLogs(); | |
135 this.$store.commit("imports/setReviewed", []); | |
136 const messages = response.data | |
137 .map(x => { | |
138 if (x.message) return x.message; | |
139 if (x.error) return x.error; | |
140 }) | |
141 .join("\n\n"); | |
142 displayInfo({ | |
143 title: "Staging Area", | |
144 message: messages, | |
145 options: { | |
146 timeout: 0, | |
147 buttons: [{ text: "Ok", action: null, bold: true }] | |
148 } | |
149 }); | |
150 }) | |
151 .catch(error => { | |
152 const { status, data } = error.response; | |
153 displayError({ | |
154 title: "Backend Error", | |
155 message: `${status}: ${data.message || data}` | |
156 }); | |
157 }); | |
158 } | |
159 }, | |
160 cancel: { | |
161 label: this.$gettext("Cancel"), | |
162 icon: "times" | |
163 } | |
164 }); | |
165 } | |
166 }, | |
167 watch: { | |
168 filters() { | |
169 this.$store.dispatch("imports/getImports", this.filters); | |
139 } | 170 } |
140 }, | 171 }, |
141 mounted() { | 172 mounted() { |
142 this.refresh(); | 173 this.loadLogs(); |
143 } | 174 } |
144 }; | 175 }; |
145 </script> | 176 </script> |
146 | |
147 <style lang="scss" scoped> | |
148 .overview { | |
149 max-height: 850px; | |
150 overflow-y: auto; | |
151 } | |
152 </style> |