11<template >
2- <section v-if =" errored" >
3- <p >{{ cdash.error }}</p >
4- </section >
5- <section v-else >
2+ <loading-indicator :is-loading =" !authenticationTokens" >
63 <data-table
74 :column-groups =" [
85 {
2421 name: 'scope',
2522 displayName: 'Scope',
2623 },
24+ {
25+ name: 'created',
26+ displayName: 'Created',
27+ },
2728 {
2829 name: 'expires',
2930 displayName: 'Expires',
3839 empty-table-text =" No authentication tokens have been created yet."
3940 >
4041 <template #scope =" { props: { scope: scope , projectname: projectname } } " >
41- <template v-if =" scope === ' submit_only ' && projectname !== null && projectname . length > 0 " >
42+ <template v-if =" scope === ' SUBMIT_ONLY ' && projectname " >
4243 Submit Only (<a
4344 class =" cdash-link"
4445 :href =" $baseURL + '/index.php?project=' + projectname"
4546 >{{ projectname }}</a >)
4647 </template >
47- <template v-else-if =" scope === ' submit_only ' " >
48+ <template v-else-if =" scope === ' SUBMIT_ONLY ' " >
4849 Submit Only
4950 </template >
5051 <template v-else >
6162 </button >
6263 </template >
6364 </data-table >
64- </section >
65+ </loading-indicator >
6566</template >
6667<script >
6768
68- import ApiLoader from ' ./shared/ApiLoader' ;
6969import DataTable from ' ./shared/DataTable.vue' ;
7070import {FontAwesomeIcon } from ' @fortawesome/vue-fontawesome' ;
7171import {faTrash } from ' @fortawesome/free-solid-svg-icons' ;
72+ import gql from ' graphql-tag' ;
73+ import LoadingIndicator from ' ./shared/LoadingIndicator.vue' ;
74+ import {DateTime } from ' luxon' ;
7275
7376export default {
7477 name: ' ManageAuthTokens' ,
75- components: {FontAwesomeIcon, DataTable},
78+ components: {LoadingIndicator, FontAwesomeIcon, DataTable},
7679
77- data () {
78- return {
79- // API results.
80- cdash: {},
81- loading: true ,
82- errored: false ,
83- };
80+ apollo: {
81+ authenticationTokens: {
82+ query: gql `
83+ query {
84+ authenticationTokens (first : 100000 ) {
85+ edges {
86+ node {
87+ id
88+ created
89+ expires
90+ description
91+ scope
92+ project {
93+ id
94+ name
95+ }
96+ user {
97+ id
98+ firstname
99+ lastname
100+ }
101+ }
102+ }
103+ }
104+ }
105+ ` ,
106+ },
84107 },
85108
86109 computed: {
@@ -91,38 +114,53 @@ export default {
91114 },
92115
93116 formattedAuthTokenRows () {
94- return Object . values (this .cdash ? . tokens ?? {} ).map (token => {
117+ return (this .authenticationTokens ? . edges ?? [] ).map (({node : token}) => {
95118 return {
96- owner: ` ${ token .owner_firstname } ${ token .owner_lastname } ` ,
119+ owner: ` ${ token .user ? . firstname } ${token .user ? . lastname }` ,
97120 description: token.description,
98121 scope: {
99122 scope: token.scope,
100- projectname: token .projectname ,
123+ projectname: token.project?.name ,
101124 },
102- expires: token .expires ,
125+ created: this.stringToDate(token.created),
126+ expires: this.stringToDate(token.expires),
103127 actions: {
104128 token: token,
105129 },
106130 };
107- }) ?? [] ;
131+ });
108132 },
109133 },
110134
111- mounted () {
112- ApiLoader .loadPageData (this , ' /api/authtokens/all' );
113- },
114-
115135 methods: {
116- revokeToken (token ) {
117- this .$axios
118- .delete (` /api/authtokens/delete/${ token .hash } ` )
119- .then (() => {
120- delete this .cdash .tokens [token .hash ];
121- })
122- .catch (error => {
123- console .log (error);
124- this .errored = true ;
136+ async revokeToken(token) {
137+ try {
138+ await this.$apollo.mutate({
139+ mutation: gql`
140+ mutation deleteAuthenticationToken ($input : DeleteAuthenticationTokenInput ! ) {
141+ deleteAuthenticationToken (input : $input ) {
142+ message
143+ }
144+ }
145+ ` ,
146+ variables: {
147+ input: {
148+ tokenId: token.id,
149+ },
150+ },
125151 });
152+ await this.$apollo.queries.authenticationTokens.refetch();
153+ }
154+ catch (error) {
155+ console.error(error);
156+ }
157+ },
158+
159+ stringToDate(isoString) {
160+ if (!isoString) {
161+ return '';
162+ }
163+ return DateTime.fromISO(isoString).toISODate();
126164 },
127165 },
128166};
0 commit comments