00:09
our existing organizations would be a perfect spot to do that. So let's hide our browser away and inside of our organization select component within
00:17
our drop down menu content, let's go ahead and add in another one of our drop down menu separators. So we can go on up to the one that we have here, give that component there a copy and
00:27
paste it just below our drop down menu radio group. We can also put a line break in between these separators here just to give them a little bit more accent whenever we're visually scanning our file.
00:37
Now underneath our new drop down separator, we can add in a new drop down menu item and
00:42
unlike our radio group, the drop down menu item is a literal clickable button inside of the drop down itself rather than a radio select.
00:51
And on this button, we just want to add the option to add an organization. And when this drop down item is clicked, we're going to open up a dialog containing
01:00
a form to add in a new organization. So we'll need a couple of state items. So let's scroll up to our script and we can do const. The first is going to be whether or not our dialog is open.
01:10
So is dialog open and we can set that to a ref with the default value of false.
01:16
Then we'll need the dialogs form so we can do const dialog form equals and we'll import use form from inertia view three and the only field that we need to get an organization
01:26
created is the organization's name. Then we can plan ahead a little bit and just have an on submit function for this dialog
01:34
as eventually we're going to add the option to edit via the dialog as well. So we'll reuse the dialog for both creating and editing.
01:41
So we can use this on submit then to determine which of those actions we're meaning to do. For now, all we want to do is take our dialog form and send out a post request to our preexisting
01:51
organization's post route that we created in our intermediary registration step when onboarding our user. Then this post will just redirect the user back to this page.
02:01
So we also want an on success handler that simply calls dialog form dot reset and we're also going to want this to close the dialog as well.
02:11
So we can do is dialog open dot value equals false. Okay, I'm going to give that a save so the format's what I have.
02:18
Now we can go ahead and scroll down below our dropdown menu and add this dialog in. First though, we'll need to hold command shift P, jump into ShotCM views, add new component
02:28
action and let's go ahead and install the dialog. It looks like they might have had an update. We'll go ahead and install that new version. That's fine. And there we go. Okay.
02:37
We can close that terminal out and to save ourselves some of the boilerplate as it's going to have boilerplate components like our dropdown menus do, we're going to extract
02:45
this out into a separate component and we're also going to make it in a way where we can reuse it for our difficulties, access levels, statuses, modules, lessons, and all of that stuff as well.
02:55
So let's go ahead and right click our component, new file, and we'll call this our form dialog dot view component. We will have a script set up lang.
03:04
Let's use TS and let's first define our props. So define props.
03:09
For this, we are going to want an open Boolean that discerns whether or not the dialog is open.
03:16
And then we'll have an editing optional Boolean that discerns whether or not this dialog is in charge of creating or editing. And then we'll have a processing Boolean, which simply tells us whether or not the form is in processing.
03:26
And then we'll also have a resource string, which will be the name of the resource that we're either creating or editing. We're also going to emit some actions from this.
03:34
So we'll do const emit equals define emits, and we'll have update open and submit.
03:41
We can normalize our open flag into a computed property, so we can do const internal open equals import computed from view there.
03:49
Define this as an object with a getter reaching for our props open flag, and then a setter
03:56
that takes in the value and emits our update open event with that value. This will allow us to internally work directly with our internal open.
04:05
It will read from our props and then update the prop accordingly if we were to set this internal open, just kind of forming that view model circle that view works with to
04:15
keep things in sync via the two-way data binding. Now let's add in our template. So we'll need ShodCN's dialog component, and much in the same way that we've set our component
04:25
up is going to have a view model open variable with two-way data binding, and we can pass that our internal open value.
04:33
Then we'll have our dialog content, and let's go ahead and give this a class small max width of 425 pixels.
04:42
To start the content out, we're going to have a dialog header, and we'll want to specify the slot title with a dialog title, and we'll do two, one for when we're editing and one
04:52
for creating. So we'll do vif editing, edit, and then we can just use our resource text to describe this.
05:00
So if we're editing an organization, this will read out edit organization, we're editing a lesson, it will read edit lesson, so on and so forth, and then we'll also want a dialog
05:08
title with a v else for when we're creating, and that will read add, and then our resource text.
05:15
Inside of our dialog content, but underneath our dialog header, we'll want to add in our form element, and we can go ahead and give this just an ID of our resource text.
05:24
That's simple enough to serve for our specific purpose, and by giving our form our ID, we're going to be able to have our button to submit the form outside of the form itself, and then
05:33
on the form we'll add a class of grid with a gap of four and a padding y of four as well.
05:39
And this is where we'll want our on submit prevent handler that emits up our submit event. The component itself doesn't care about what is submitting, how it's submitting, it's just
05:48
going to bubble that event up. And then our form, we'll add our slot as the content. Lastly, we want our dialog footer to round this component out.
05:58
That will be a button of type submit, and then we'll specify the form of this button
06:02
as our resource text, which just binds this submit button to our form via the form's ID,
06:10
and then our form attribute on the button itself. And we can go ahead and disable this button when our form is processing.
06:17
We can also add in our loader component from LucideView next as its icon, and show this
06:22
vif processing, add in a class of margin right two, width four, height four, and then go ahead and animate spin to make it do its spinning animation.
06:32
And then just like our dialog title, we're going to want a span with a vif when we're editing, we'll show update resource, and then a span of the else when we're creating, we'll
06:42
show add resource. Awesome. So that is our form dialog component, and it's big enough where we're going to be able to reuse this for each and every one of our resources.
06:51
And we'll start out with adding it to our organization select. So underneath our dropdown menu, let's go ahead and add in our form dialog component there.
06:59
The one and only field for this form is going to be our form input for our name input.
07:05
View model, bind that to our dialog form dot name value, as well as the error through dialog form, errors, name.
07:14
Next we need to set up the props of our form dialog. So we'll start by defining our resource text as organization so that this reads update
07:22
organization, add organization, as we've set up inside of this component. Then we'll want our view model open, bound to our is dialog open state there.
07:32
And then we can bind the processing to our dialog form dot processing flag. And then we'll leave editing off, and we'll save that for whenever we rig up our editing capabilities.
07:41
For now, we'll just take in that submit event and pass that along to our on submit handler. Lastly, our on click for our add organization dropdown menu button.
07:51
We want this to set our is dialog open value to true. Okay, let's go and jump into our browser now, take a look at our dropdown menu. There is our add organization option.
08:00
If we give that a click, there's our add organization dialog, and we can type out my, and we already have two. So we'll do third organization to test this out.
08:09
Let's hit add organization and let's see if it worked. So there we go. We have my third organization in there now. What we really want to have happen though, is whenever we create that organization, the
08:19
newly created organization should become our new active organization. So we need to rig that up next. So let's hide our browser back away.
08:26
And for this, we'll want to jump into our organizations controller. After we've stored and created the organization inside of our controller store method, what
08:35
we want to do is call our set active organization action. And this is part of our get active organization flow.
08:42
So if we jump into our get active organization, this is the action that we want to call inside of our organizations controller whenever we're creating a brand new organization. And this injects our HTTP context.
08:52
So we'll also want to inject it into our store method. However, we're going to need multiple methods inside of this controller because we're also
09:00
going to need the ability to swap between our organizations as well, which will again need to do that exact same thing. So we can, instead of injecting it directly into our store method, just jump up to our
09:09
organizations controller, add in a constructor, protected set active organization of type set active organization and import that action in.
09:20
Then we'll decorate our organizations controller with AdonisJS Core's inject decorator there. With that, we can now come down to our store method and call this set active organization,
09:30
call the handle method and pass the ID in as our newly created organization ID. With that set up, we jump back into our browser. Let's go ahead and add one more organization.
09:39
So we'll do my fourth organization. We can add that organization and now we're automatically switched to my fourth organization rather than my first organization.
09:48
Although it does look like we have a little fix to do for which one is set as active inside of our dropdown. Because right now it's still showing my first organization as our active one, but clearly
09:58
my fourth organization is the one where the data is actually loaded in. So let's go ahead and give our page a refresh and let's check that out one more time. So now you can see it's correct.
10:07
My fourth organization is now our selected organization. The reason that this happened, if we had our browser back away, let's jump back into our
10:13
organization, select and scroll up to where we're ingesting in that organization ID. So whenever this component's created, we're creating a ref out of our props organization
10:22
ID and converting it to string for that radio buttons compatibility sake. This is a one-time event, meaning that if our props organization ID changes at all in
10:30
the future, which we just saw happen, this organization ID value is not going to update along with it. And we definitely want it to.
10:38
Thankfully, there's a quick and easy option that we can use with Vue called watch effect. So we can import this from Vue and this takes a callback function.
10:46
Inside of this callback function, let's go ahead and write what we want here first, and then I'll walk through what it's doing.
10:51
So we'll set our organization ID value to our props organization ID.
10:57
And then again, convert that to string for compatibility sake with our radio button dropdown. What Vue is going to do here is watch the items inside of this callback function for
11:07
changes. Whenever it finds a change effect against one of these reactive variables, it's going to execute this callback function.
11:14
So if our prop organization ID changes, this callback function will get executed, which will then update our organization ID value.
11:22
So this one line here has essentially fixed the issue that we've just seen. So if we give that a save and jump back into our browser, let's try this one more time by creating our fifth organization.
11:32
So we'll do my fifth organization. We can hit add there. Our active organization is now my fifth organization.
11:39
And if we open up our dropdown, the active organization in here is now my fifth organization as well. And we'll see this populate true as well whenever we add in the ability to swap what the active
11:49
organization is too.