Skip to content

Commit 1a4823b

Browse files
authored
Merge pull request #1218 from MetRonnie/alert-snack
Replace alert bar with snackbar
2 parents 6d1a589 + b9fe3a8 commit 1a4823b

File tree

18 files changed

+109
-133
lines changed

18 files changed

+109
-133
lines changed

src/components/core/Alert.vue

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,65 +16,61 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
-->
1717

1818
<template>
19-
<div v-if="alert">
20-
<v-alert
21-
:value="true"
22-
:type="alert.color"
23-
:icon="alert.icon"
24-
:class="getColor(alert.color)"
25-
dismissible
26-
tile
27-
light
28-
colored-border
29-
>
30-
<template v-slot:close="props">
31-
<v-icon @click="closeAlert(props.toggle)">{{ svgPaths.close }}</v-icon>
32-
</template>
33-
{{ alert.text }}
34-
</v-alert>
35-
</div>
19+
<v-snackbar
20+
v-if="alert"
21+
v-model="alert"
22+
:color="getColor(alert.color)"
23+
top
24+
timeout="-1"
25+
data-cy="alert-snack"
26+
>
27+
<template v-slot:action="{ attrs }">
28+
<v-btn
29+
icon
30+
v-bind="attrs"
31+
@click="closeAlert"
32+
data-cy="snack-close"
33+
>
34+
<v-icon>{{ $options.icons.mdiClose }}</v-icon>
35+
</v-btn>
36+
</template>
37+
{{ alert.text }}
38+
</v-snackbar>
3639
</template>
3740

3841
<script>
3942
import { mdiClose } from '@mdi/js'
4043
import { mapActions, mapState } from 'vuex'
4144
45+
// TODO: remove later when https://github.com/vuetifyjs/vuetify/issues/11021 is fixed
46+
const colors = new Map([
47+
['error', 'red'],
48+
['success', 'green'],
49+
['warning', 'amber']
50+
])
51+
4252
export default {
4353
name: 'Alert',
4454
45-
data () {
46-
return {
47-
// TODO: remove later when https://github.com/vuetifyjs/vuetify/issues/11021 is fixed
48-
colors: new Map([
49-
['error', 'red'],
50-
['success', 'green'],
51-
['warning', 'amber']
52-
]),
53-
svgPaths: {
54-
close: mdiClose
55-
}
56-
}
57-
},
58-
5955
computed: {
6056
...mapState(['alert'])
6157
},
6258
6359
methods: {
6460
...mapActions(['setAlert']),
6561
getColor (type) {
66-
return this.colors.get(type) || ''
62+
return colors.get(type) || ''
6763
},
6864
/**
6965
* Dismisses the alert from the UI, also removing it from the Vuex store.
70-
*
71-
* @param {Function} toggleFunction - the original Vuetify toggle function
72-
* @see https://vuetifyjs.com/en/api/v-alert/
7366
*/
74-
closeAlert (toggleFunction) {
67+
closeAlert () {
7568
this.setAlert(null)
76-
toggleFunction()
7769
}
70+
},
71+
72+
icons: {
73+
mdiClose
7874
}
7975
}
8076
</script>

src/components/cylc/Mutation.vue

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
116116
</v-tooltip>
117117
</v-card-actions>
118118
<v-snackbar
119-
v-model="showSnackbar"
120-
v-bind="snackbarProps"
121-
data-cy="response-snackbar"
119+
v-model="showWarning"
120+
timeout="4e3"
121+
color="amber accent-2"
122+
light
123+
data-cy="warning-snack"
122124
>
123-
{{ response.msg }}
125+
{{ warningMsg }}
124126
<template v-slot:action="{ attrs }">
125127
<v-btn
126-
@click="showSnackbar = false"
128+
@click="showWarning = false"
127129
icon
128130
v-bind="attrs"
129-
data-cy="snackbar-close"
131+
data-cy="snack-close"
130132
>
131133
<v-icon>
132134
{{ $options.icons.close }}
@@ -143,7 +145,8 @@ import EditRuntimeForm from '@/components/graphqlFormGenerator/EditRuntimeForm.v
143145
import Markdown from '@/components/Markdown'
144146
import {
145147
getMutationShortDesc,
146-
getMutationExtendedDesc
148+
getMutationExtendedDesc,
149+
mutationStatus
147150
} from '@/utils/aotf'
148151
import { mdiClose } from '@mdi/js'
149152
@@ -186,10 +189,7 @@ export default {
186189
data: () => ({
187190
isValid: false,
188191
submitting: false,
189-
response: {
190-
msg: null,
191-
level: 'warn'
192-
}
192+
warningMsg: null
193193
}),
194194
195195
computed: {
@@ -201,26 +201,13 @@ export default {
201201
extendedDescription () {
202202
return getMutationExtendedDesc(this.mutation.description)
203203
},
204-
showSnackbar: {
204+
showWarning: {
205205
get () {
206-
return Boolean(this.response.msg)
206+
return Boolean(this.warningMsg)
207207
},
208208
set (val) {
209-
if (!val) this.response.msg = null
209+
if (!val) this.warningMsg = null
210210
}
211-
},
212-
snackbarProps () {
213-
return this.response.level === 'error'
214-
? {
215-
timeout: -1,
216-
color: 'red accent-2',
217-
dark: true
218-
}
219-
: {
220-
timeout: 4e3,
221-
color: 'amber accent-2',
222-
light: true
223-
}
224211
}
225212
},
226213
@@ -230,16 +217,13 @@ export default {
230217
this.submitting = true
231218
this.$refs.form.submit().then(response => {
232219
this.submitting = false
233-
if (response.status.name.includes('failed')) {
234-
this.response.msg = response.message
235-
this.response.level = 'error'
236-
} else if (response.status.name === 'warn') {
237-
this.response.msg = response.message
238-
this.response.level = 'warn'
239-
} else {
220+
if (response.status === mutationStatus.SUCCEEDED) {
240221
// Close the form on success
241222
this.cancel()
223+
} else if (response.status === mutationStatus.WARN) {
224+
this.warningMsg = response.message
242225
}
226+
// else if error, an alert is generated by AOTF
243227
})
244228
}
245229
},

src/components/graphqlFormGenerator/EditRuntimeForm.vue

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ import { mdiHelpCircleOutline } from '@mdi/js'
6262
import { cloneDeep, isArray, isEqual, snakeCase, startCase } from 'lodash'
6363
import { VTextarea } from 'vuetify/lib/components'
6464
import VuetifyConfig, { getComponentProps, RUNTIME_SETTING } from '@/components/graphqlFormGenerator/components/vuetify'
65-
import { findByName, mutate } from '@/utils/aotf'
65+
import { findByName, mutate, mutationStatus } from '@/utils/aotf'
6666
6767
export default {
6868
name: 'EditRuntimeForm',
@@ -161,9 +161,7 @@ export default {
161161
if (!settings.length) {
162162
return {
163163
message: 'No changes were made',
164-
status: {
165-
name: 'warn'
166-
}
164+
status: mutationStatus.WARN
167165
}
168166
}
169167
const args = {

src/graphql/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export function createSubscriptionClient (wsUrl, options = {}, wsImpl = null) {
9797
// would be nice to find a better error message using the error object
9898
// subscriptionClient.onError((error) => {
9999
// console.error(error)
100-
// store.commit('SET_ALERT', new Alert(error, null, 'error'))
100+
// store.commit('SET_ALERT', new Alert(error, 'error'))
101101
// })
102102
return subscriptionClient
103103
}

src/layouts/Default.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export default {
8787
8888
errorCaptured (error, vm, info) {
8989
if (process.env.NODE_ENV !== 'production') {
90-
store.dispatch('setAlert', new AlertModel(error, null, 'error'))
90+
store.dispatch('setAlert', new AlertModel(error, 'error'))
9191
}
9292
}
9393
}

src/model/Alert.model.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@
1616
*/
1717

1818
export default class Alert {
19-
constructor (text, icon, color) {
19+
constructor (text, color) {
2020
this.text = text
21-
this.icon = icon
2221
this.color = color
2322
}
2423
}

src/model/Subscription.model.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class Subscription {
7474
} else {
7575
Object.values(this.subscribers).forEach(function (subscriber) {
7676
subscriber.viewState = viewState
77-
subscriber.setAlert(new Alert(context.message, null, 'error'))
77+
subscriber.setAlert(new Alert(context.message, 'error'))
7878
if (_this.debug) {
7979
// eslint-disable-next-line no-console
8080
console.debug(`Subscription error: ${context.message}`, viewState, context)

src/router/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ router.beforeEach((to, from, next) => {
9696
next()
9797
})
9898
.catch(error => {
99-
const alert = new Alert(error, null, 'error')
99+
const alert = new Alert(error, 'error')
100100
return store.dispatch('setAlert', alert)
101101
})
102102
} else {

src/services/workflow.service.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ class WorkflowService {
227227
if (callback.init) {
228228
callback.init(store, errors)
229229
for (const error of errors) {
230-
store.commit('SET_ALERT', new Alert(error[0], null, 'error'), { root: true })
230+
store.commit('SET_ALERT', new Alert(error[0], 'error'), { root: true })
231231
// eslint-disable-next-line no-console
232232
console.warn(...error)
233233
subscription.handleViewState(ViewState.ERROR, error('Error presetting view state'))
@@ -340,7 +340,7 @@ class WorkflowService {
340340
for (const error of errors) {
341341
store.commit(
342342
'SET_ALERT',
343-
new Alert(error[0], null, 'error'),
343+
new Alert(error[0], 'error'),
344344
{ root: true }
345345
)
346346
// eslint-disable-next-line no-console

src/utils/aotf.js

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ import {
4747
mdiStop
4848
} from '@mdi/js'
4949

50-
import AlertModel from '@/model/Alert.model'
51-
import TaskState from '@/model/TaskState.model'
50+
import Alert from '@/model/Alert.model'
5251
import store from '@/store/index'
5352
import { Tokens } from '@/utils/uid'
5453

@@ -108,7 +107,7 @@ import { IntrospectionInputType } from 'graphql'
108107

109108
/**
110109
* @typedef {Object} MutationResponse
111-
* @property {TaskState} status
110+
* @property {string} status
112111
* @property {string} message
113112
*/
114113

@@ -280,11 +279,9 @@ export const alternateFields = {
280279
* Maps onto task status.
281280
*/
282281
export const mutationStatus = Object.freeze({
283-
[TaskState.WAITING]: TaskState.WAITING,
284-
[TaskState.SUBMITTED]: TaskState.SUBMITTED,
285-
[TaskState.SUCCEEDED]: TaskState.SUCCEEDED,
286-
[TaskState.FAILED]: TaskState.FAILED,
287-
[TaskState.SUBMIT_FAILED]: TaskState.SUBMIT_FAILED
282+
FAILED: 'FAILED',
283+
SUCCEEDED: 'SUCCEEDED',
284+
WARN: 'WARN'
288285
})
289286

290287
/**
@@ -831,6 +828,17 @@ export function getMutationArgsFromTokens (mutation, tokens) {
831828
return argspec
832829
}
833830

831+
/**
832+
* @param {string} message
833+
* @returns {MutationResponse}
834+
*/
835+
function _mutateSuccess (message) {
836+
return {
837+
status: mutationStatus.SUCCEEDED,
838+
message
839+
}
840+
}
841+
834842
/**
835843
* Handle an error in a called mutation.
836844
*
@@ -848,15 +856,14 @@ async function _mutateError (mutationName, message, response) {
848856
}
849857

850858
// open a user alert
851-
await store.dispatch('setAlert', new AlertModel(
852-
`command failed: ${mutationName} - ${message}`,
853-
null,
854-
'error')
859+
await store.dispatch(
860+
'setAlert',
861+
new Alert(`Command failed: ${mutationName} - ${message}`, 'error')
855862
)
856863

857864
// format a response
858865
return {
859-
status: TaskState.SUBMIT_FAILED,
866+
status: mutationStatus.FAILED,
860867
message
861868
}
862869
}
@@ -869,7 +876,7 @@ async function _mutateError (mutationName, message, response) {
869876
* @param {ApolloClient} apolloClient
870877
* @param {string=} cylcID
871878
*
872-
* @returns {Promise<MutationResponse>} {status, msg}
879+
* @returns {(MutationResponse | Promise<MutationResponse>)} {status, msg}
873880
*/
874881
export async function mutate (mutation, variables, apolloClient, cylcID) {
875882
const mutationStr = constructMutation(mutation)
@@ -898,24 +905,18 @@ export async function mutate (mutation, variables, apolloClient, cylcID) {
898905
}
899906

900907
try {
901-
const result = response.data[mutation.name].result
908+
const { result } = response.data[mutation.name]
902909
if (Array.isArray(result) && result.length === 2) {
903910
// regular [commandSucceeded, message] format
904911
if (result[0] === true) {
905912
// success
906-
return {
907-
status: TaskState.SUBMITTED,
908-
message: result[1]
909-
}
913+
return _mutateSuccess(result[1])
910914
}
911915
// failure (Cylc error, e.g. could not find workflow <x>)
912916
return _mutateError(mutation.name, result[1], response)
913917
}
914918
// command in a different format (e.g. info command)
915-
return {
916-
status: TaskState.SUBMITTED,
917-
message: result
918-
}
919+
return _mutateSuccess(result)
919920
} catch (error) {
920921
return _mutateError(mutation.name, 'invalid response', response)
921922
}

0 commit comments

Comments
 (0)