All right, so I'm back with our web application opened up to our organization settings page. Let's go ahead and start by getting that card added into this page itself.
So within our inertia directory, we're going to want to go into our components and right click it and add a new file in.
We'll call this our organization access tokens card.vue. Let's get ourselves a setup script
with TypeScript added to the top, as well as a template. We'll start by getting our card directly added into our template.
So we'll add our card in here with a card header and a card title with the title organization access tokens.
Let me go ahead and collapse the sidebar away, give us a little bit more working room. Underneath that title, we'll have a card description
of manage tokens your organization can use to access our API.
Underneath the header itself, we'll have our card content, which for now, let's go ahead and just put our button in
to create the access token. So we'll do flex justify end to put that to the right side and a margin top of four, because inevitably, we will be putting a table in here
to list our access tokens as well. We'll add a button in with a type of button and the text add access token.
Now, apologies, before we get too far, I should note that we are using ShodCM view as our view component library, in addition to UnpluggedIn view components.
So ShodCM view installs all of their components locally and they're housed within this components UI directory. So here's where that card component is and then all the card components that we're making use of.
And then UnpluggedIn view components is going to automatically import these as we use them within our template so that we don't have to worry about managing or dealing with imports throughout the series.
So that's why I'm not taking any of the time to actually import these components that UnpluggedIn view components is going to do it automatically for me and you as well. But I do have that set to only work
on components local to our project. So if we reach for any components from our node modules, we will need to import those. Okay, so we should be able to give that a save then
and use this as our starting point. Let's go get it added onto our page that we can actually start seeing it take effect. So we'll want to dive down into our pages directory
within Inertia and we have a settings folder with our organization.view page inside of it. Within here for our template,
we have a setting shell with our organization edit card, our organization users card and our organization user invites card. Each one of those being a card on the page here.
So we just want to add to this our organization access tokens card, just like so. Now, currently we're not accepting any props into it.
We will eventually, but we can give that a save as is for right now. And now if we jump over into our browser, we should be able to scroll down a little bit and actually see this card come to play.
So we have our add access tokens button right there. That's what we're going to be continuing on with next. So let's jump back into our card. When this button to add an access token is clicked,
we're gonna want to show our dialogue to create the access token. So we'll do is dialogue shown and set that to true. Go ahead and break that down so that everything stays on the page here.
Okay, within our script then we want to define that ref. So we do const is dialogue shown equals ref and set that to false.
Let's go ahead and import ref from view as well. Underneath our card then we can add that dialogue into our page. That too is a ShotCM view component
and pass it the view model for the open flag, our is dialogue shown flag from our ref. Inside of this dialogue,
we can do our dialogue content with a dialogue header and a dialogue title of add access token.
Underneath our headers where our form is going to go. So we can add our form in and let's leave the at submit handler off of it for right now.
On our form, we'll want a form input and we can self-close that because we need to provide it some props. First we'll want the label of name, set the type to text,
add a class of flex one so that it goes the full width of the dialogue. Find the view model. We'll set up a form here momentarily with a name property on it.
Then we can set this field to be disabled when this form is processing. Now, remember the handler we're gonna end up sending this form to is not going to respond
as an inertia request. Rather we're going to send this with Axios and get back a straight JSON response. So we're actually not gonna use inertia
for either our form or whether or not it's processing. We'll just use simple reps for those. So let's scroll back up to our script and add those in.
So we'll do const form equals ref with an object, set that to an empty string for name and then permissions, which we can set to a new
and let's use a set for this, adding the default value to read. Now, after our name field, we're going to have a checkbox list for our permission options. So let's add that here as well.
So permission options equals and we can just use an object dot value of our token actions. And I'm not getting auto-complete here.
So I'm just gonna go ahead and reload my window. There we go. Visual Studio Code tends to have a problem with brand new view components where it doesn't pick up like TypeScript
or auto-complete style things. So just reloading the window there tends to fix that. So let's go and try reaching for our token actions again. There we go, that's better. And it is now also telling me
that that should be object values. Okay, so to reload my window, all I did was hold command shift and P and then search for reload window and selected the developer reload window option there
in case that is happening to you. Then we also have that processing flag. So we'll add that in as well. So processing equals ref and just default that to false.
And we can move that up with our other Boolean there so that they're side by side. All right, next let's go ahead and get our checkboxes added for our permissions.
So for this, we'll do a div with a class flex, flex call gap one margin Y three, and we'll add a ShotCM view label called permissions
and then a form input with a type of group. This form input component is a custom wrapper around ShotCM views input component.
So that's why the props are gonna look a little bit different here from ShotCM views input. And then inside of this, we can loop over using V4,
each option in our permission options, set the key to the option itself
and then set the class to flex items center gap two. Within this div, we'll put our actual checkbox.
So we'll do check box and self-close that. Since we're using a set for the permissions array, we'll go ahead and handle this a little bit differently.
So we'll do checked equals form permissions has and check whether or not it has the option that we're looping over. And then when the checked is updated,
we'll see whether or not the checkbox was checked and that'll be the event directly itself. So this will be a Boolean true if it was checked, false if it was not.
So when it has been checked, we're gonna want to reach for our form permissions and add the option. And when it's not checked, we'll want to remove it.
So form permissions, delete option. And then again, we can go ahead and disable this when our form is processing. Underneath the checkbox,
we can put a span class capitalize of the option itself. Then underneath our form, we can go ahead and round the dialog out
with a dialog footer that has a button of type submit. We set this to disabled when our form is processing
and bind it to our form. So we'll call this our access token dialog. And when you specify form to a button,
it will bind that button to the ID of the attribute value. So if we give access token dialog there a copy, go up to our form and give our form
the ID of access token dialog. Whenever we click or hit enter with this button, it will treat it as an actual submission for the form itself,
despite the button not actually being within the form's contents. Okay, let's do our loader then within the button. And this component does come from Lucide View Next and it's NPM package.
So we want to actually import this. We do VIF processing and give it a class of margin right to H4 width four and animate spin.
Then close that off and add in our actual text of create access token. All right, so if we give this card here a save,
come now over into our browser and click add access token. We actually don't see anything happen and that's 'cause I can't spell.
So I have dialog rather than dialog here. So I'm just gonna do a quick search for that dialog misspelling and correct that to dialog.
Replace all of those, give it a save. Oh, all right, there we go. Without doing anything, it showed up now. So let's go ahead and refresh our browser just to make sure that I have, you know, the latest of everything there.
Let's try clicking add access token again. There we go. So now we see our access token dialog here. What we wanna do next is actually rig this up now
to the route endpoint that we set up in the last lesson to actually create our access token. So let's close out of that. And I'm gonna scroll that all the way down there.
And we'll want to handle this actual form submission. So we'll add an @submit.prevent to it
and add a function called on submit to our script. So we'll scroll on up to our script here and add an async function on submit. And within here, the very first thing
that we're gonna wanna do is switch our processing flag to true to disable our form inputs and buttons within that dialog. Once we have that switched on,
we can send off our API request, getting our data back and send it using await Axios. Now, you know what?
I actually don't think we have Axios installed here. Inertia does use it underneath the hood. So let's go ahead and jump over into our terminal
and just do npm i axios really quick to get that installed within our project as a direct dependency. All right, we jump back into our browser there. And now let's try to, yep, there we go.
Import Axios and we can send off a post request to our /settings/organization/access-tokens endpoint,
passing it as its payload, the name from our form.value name,
and then the permissions as an array from our form value permissions. Once we have that response back,
we can go ahead and switch our processing flag back to false as it's now done working. Then within our browser, let's go ahead and right click and inspect.
And let's jump into the network panel here so that we can take a look at the direct network request that's sent. And let's try to add in an access token. We'll just give this a name of test01.
And let's check all of the permissions just to make sure that they're all going to work okay. Let's create our access token. And we see that sent off with our post request. And let's check out and see what the response is.
So for our response, we get back our access token property with its ID, the token's type, the token's name, the access token itself, which is what we'll inevitably want to do display
to our users so that they can copy it to their clipboard and make use of it with our API, the token's abilities when it was created and when it was last updated. Furthermore, we should now be able to jump back
into TablePlus, jump into our API database and take a look at our access tokens table to see that we do indeed have this record within there
with the name of test01 and its abilities, I misclicked, there we go. Its ability is a recreate, update and delete.
The tokenable ID here specifies that the access token is for our organization with an ID of one. If we click on the little arrow icon there,
it will actually take us to that organization record, verifying that that is the foreign key relationship for that. And then the type here is the purpose of the token,
which is an API token. So awesome. That's all working A-okay. Let's go ahead and just entertain ourselves and create another one. We'll just read and create. And we'll call this test02.
Send that off. Let's take a look at the next request for that. Get back an ID of two with a name of test02 and abilities of just read and create. Awesome.
So that's working perfectly fine now. The next step of this form flow is to, rather than show the user the form after they've submitted, to instead show the user the token directly
so that they can copy it to their clipboard. But before we do that, let's get these tokens listing within our organization access tokens card.
Creating Access Tokens Part 2: Inertia/Vue
In This Lesson
We'll rig up the create access token route we created in the last lesson to a form within our Vue application. We'll also stub the overall manage access tokens card for the organization itself.
If you're just here for the API stuff and don't care for the Inertia/Vue side of this application, please feel free to apply the below code changes and continue onward. I'll also have the completed Inertia/Vue code available in the last lesson of this API Authentication module if you'd prefer waiting for that!
First, create a new file at inertia/components/OrganizationAccessTokensCard.vue with the following contents:
We'll expand on this a little further in future lessons, again, I'll have the completed code you can copy/paste if you're not interested in the Vue/Inertia side of this application in the last lesson of this API Authentication module.