mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-10-31 02:03:35 -04:00 
			
		
		
		
	feature/profile-cards (#391)
* unify format * pass variables * remove namespace * rename * group-card init * shuffle + icons * remove console.logs * token CRUD * update changelog * add profile link * consolidate mealplan to profile dashboard * update docs * add query parameter to search page * update test routes * update python depts * basic token tests Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
		
							
								
								
									
										147
									
								
								frontend/src/pages/Admin/Profile/APITokenCard.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								frontend/src/pages/Admin/Profile/APITokenCard.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
| <template> | ||||
|   <StatCard icon="mdi-api" color="accent"> | ||||
|     <template v-slot:after-heading> | ||||
|       <div class="ml-auto text-right"> | ||||
|         <div class="body-3 grey--text font-weight-light" v-text="'API Tokens'" /> | ||||
|         <h3 class="display-2 font-weight-light text--primary"> | ||||
|           <small> {{ user.tokens.length }} </small> | ||||
|         </h3> | ||||
|       </div> | ||||
|     </template> | ||||
|     <template v-slot:bottom> | ||||
|       <v-subheader class="mb-n2">ACTIVE TOKENS</v-subheader> | ||||
|       <v-virtual-scroll height="210" item-height="70" :items="user.tokens" class="mt-2"> | ||||
|         <template v-slot:default="{ item }"> | ||||
|           <v-divider></v-divider> | ||||
|           <v-list-item @click.prevent> | ||||
|             <v-list-item-avatar> | ||||
|               <v-icon large dark color="accent"> | ||||
|                 mdi-api | ||||
|               </v-icon> | ||||
|             </v-list-item-avatar> | ||||
|  | ||||
|             <v-list-item-content> | ||||
|               <v-list-item-title v-text="item.name"></v-list-item-title> | ||||
|             </v-list-item-content> | ||||
|  | ||||
|             <v-list-item-action class="ml-auto"> | ||||
|               <v-btn large icon @click.stop="deleteToken(item.id)"> | ||||
|                 <v-icon color="accent">mdi-delete</v-icon> | ||||
|               </v-btn> | ||||
|             </v-list-item-action> | ||||
|           </v-list-item> | ||||
|           <v-divider></v-divider> | ||||
|         </template> | ||||
|       </v-virtual-scroll> | ||||
|  | ||||
|       <v-divider></v-divider> | ||||
|       <v-card-actions class="pb-1 pt-3"> | ||||
|         <v-spacer></v-spacer> | ||||
|         <BaseDialog | ||||
|           :title="'Create an API Token'" | ||||
|           title-icon="mdi-api" | ||||
|           @submit="createToken" | ||||
|           :submit-text="buttonText" | ||||
|           :loading="loading" | ||||
|         > | ||||
|           <v-card-text> | ||||
|             <v-form ref="newTokenForm"> | ||||
|               <v-text-field v-model="name" label="Token Name" required> </v-text-field> | ||||
|             </v-form> | ||||
|  | ||||
|             <div v-if="createdToken != ''"> | ||||
|               <v-textarea | ||||
|                 class="mb-0 pb-0" | ||||
|                 label="API Token" | ||||
|                 readonly | ||||
|                 v-model="createdToken" | ||||
|                 append-outer-icon="mdi-content-copy" | ||||
|                 @click:append-outer="copyToken" | ||||
|               > | ||||
|               </v-textarea> | ||||
|               <v-subheader class="text-center"> | ||||
|                 Copy this token for use with an external application. This token will not be viewable again. | ||||
|               </v-subheader> | ||||
|             </div> | ||||
|           </v-card-text> | ||||
|  | ||||
|           <template v-slot:open="{ open }"> | ||||
|             <v-btn color="success" @click="open"> | ||||
|               <v-icon left> mdi-plus </v-icon> | ||||
|               {{ $t("general.create") }} | ||||
|             </v-btn> | ||||
|           </template> | ||||
|         </BaseDialog> | ||||
|       </v-card-actions> | ||||
|     </template> | ||||
|   </StatCard> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import BaseDialog from "@/components/UI/Dialogs/BaseDialog"; | ||||
| import StatCard from "@/components/UI/StatCard"; | ||||
| import { api } from "@/api"; | ||||
| import { validators } from "@/mixins/validators"; | ||||
| import { initials } from "@/mixins/initials"; | ||||
| export default { | ||||
|   components: { | ||||
|     BaseDialog, | ||||
|     StatCard, | ||||
|   }, | ||||
|   mixins: [validators, initials], | ||||
|   data() { | ||||
|     return { | ||||
|       name: "", | ||||
|       loading: false, | ||||
|       createdToken: "", | ||||
|     }; | ||||
|   }, | ||||
|  | ||||
|   mounted() { | ||||
|     this.$store.dispatch("requestUserData"); | ||||
|   }, | ||||
|  | ||||
|   computed: { | ||||
|     user() { | ||||
|       return this.$store.getters.getUserData; | ||||
|     }, | ||||
|     buttonText() { | ||||
|       if (this.createdToken === "") { | ||||
|         return "Create"; | ||||
|       } else { | ||||
|         return "Close"; | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     async createToken() { | ||||
|       if (this.loading === true) { | ||||
|         this.loading = false; | ||||
|         this.$store.dispatch("requestUserData"); | ||||
|         this.createdToken = ""; | ||||
|         this.name = ""; | ||||
|         return; | ||||
|       } | ||||
|       this.loading = true; | ||||
|       if (this.$refs.newTokenForm.validate()) { | ||||
|         const response = await api.users.createAPIToken(this.name); | ||||
|         this.createdToken = response.token; | ||||
|       } | ||||
|     }, | ||||
|     async deleteToken(id) { | ||||
|       await api.users.deleteAPIToken(id); | ||||
|       this.$store.dispatch("requestUserData"); | ||||
|     }, | ||||
|     copyToken() { | ||||
|       const copyText = this.createdToken; | ||||
|       navigator.clipboard.writeText(copyText).then( | ||||
|         () => console.log("Copied", copyText), | ||||
|         () => console.log("Copied Failed", copyText) | ||||
|       ); | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style></style> | ||||
		Reference in New Issue
	
	Block a user