diff --git a/apps/cyberstorm-remix/app/settings/teams/team/tabs/ServiceAccounts/ServiceAccounts.css b/apps/cyberstorm-remix/app/settings/teams/team/tabs/ServiceAccounts/ServiceAccounts.css index 474e84913..9a1ca6a1a 100644 --- a/apps/cyberstorm-remix/app/settings/teams/team/tabs/ServiceAccounts/ServiceAccounts.css +++ b/apps/cyberstorm-remix/app/settings/teams/team/tabs/ServiceAccounts/ServiceAccounts.css @@ -38,6 +38,14 @@ line-height: var(--line-height-bold); } + .service-accounts__form { + display: flex; + flex-direction: column; + gap: var(--gap-md); + align-items: flex-start; + align-self: stretch; + } + .service-accounts__nickname-input { display: flex; flex-direction: row; diff --git a/apps/cyberstorm-remix/app/settings/teams/team/tabs/ServiceAccounts/ServiceAccounts.tsx b/apps/cyberstorm-remix/app/settings/teams/team/tabs/ServiceAccounts/ServiceAccounts.tsx index 704782324..fa5467811 100644 --- a/apps/cyberstorm-remix/app/settings/teams/team/tabs/ServiceAccounts/ServiceAccounts.tsx +++ b/apps/cyberstorm-remix/app/settings/teams/team/tabs/ServiceAccounts/ServiceAccounts.tsx @@ -8,7 +8,6 @@ import { NewTextInput, Heading, CodeBox, - useToast, } from "@thunderstore/cyberstorm"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faPlus } from "@fortawesome/free-solid-svg-icons"; @@ -73,6 +72,11 @@ export default function ServiceAccounts() { const revalidator = useRevalidator(); + const currentUserTeam = outletContext.currentUser?.teams_full?.find( + (team) => team.name === teamName + ); + const isOwner = currentUserTeam?.role === "owner"; + async function serviceAccountRevalidate() { revalidator.revalidate(); } @@ -116,11 +120,13 @@ export default function ServiceAccounts() {

Service accounts

Your loyal servants

- + {isOwner && ( + + )}
(null); function onSuccess( result: Awaited> @@ -155,8 +162,6 @@ function AddServiceAccountForm(props: { setAddedServiceAccountNickname(result.nickname); } - const toast = useToast(); - function formFieldUpdateAction( state: TeamServiceAccountAddRequestData, action: { @@ -174,6 +179,8 @@ function AddServiceAccountForm(props: { nickname: "", }); + const isValid = formInputs.nickname.trim().length > 0; + type SubmitorOutput = Awaited>; async function submitor(data: typeof formInputs): Promise { @@ -181,7 +188,7 @@ function AddServiceAccountForm(props: { config: props.config, params: { team_name: props.teamName }, queryParams: {}, - data: { nickname: data.nickname }, + data: { nickname: data.nickname.trim() }, }); } @@ -201,18 +208,15 @@ function AddServiceAccountForm(props: { submitor, onSubmitSuccess: (result) => { onSuccess(result); - toast.addToast({ - csVariant: "success", - children: `Service account added`, - duration: 4000, - }); + setError(null); + // Refresh the service accounts list to show the newly created account + // TODO: When API returns identifier in response, we can append the new + // service account to the list instead of refreshing from backend + props.serviceAccountRevalidate?.(); }, onSubmitError: (error) => { - toast.addToast({ - csVariant: "danger", - children: `Error occurred: ${error.message || "Unknown error"}`, - duration: 8000, - }); + const message = `Error occurred: ${error.message || "Unknown error"}`; + setError(message); }, }); @@ -222,6 +226,7 @@ function AddServiceAccountForm(props: { setServiceAccountAdded(false); setAddedServiceAccountToken(""); setAddedServiceAccountNickname(""); + setError(null); updateFormFieldState({ field: "nickname", value: "" }); } }; @@ -257,30 +262,44 @@ function AddServiceAccountForm(props: { ) : ( -
- Enter the nickname of the service account you wish to add to the - team {props.teamName} -
-
- { - updateFormFieldState({ - field: "nickname", - value: e.target.value, - }); - }} - placeholder={"ExampleName"} - maxLength={32} - /> -
- Max. 32 characters +
{ + e.preventDefault(); + if (isValid) { + strongForm.submit(); + } + }} + > +
+ Enter the nickname of the service account you wish to add to the + team {props.teamName}
-
+
+ { + updateFormFieldState({ + field: "nickname", + value: e.target.value, + }); + }} + placeholder={"ExampleName"} + maxLength={32} + /> +
+ Max. 32 characters +
+
+ {error && {error}} + )} {serviceAccountAdded ? null : ( - Add Service Account + + Add Service Account + )} diff --git a/apps/cyberstorm-remix/app/styles/settingsItem.css b/apps/cyberstorm-remix/app/styles/settingsItem.css index 7c3e36d82..fa642ef68 100644 --- a/apps/cyberstorm-remix/app/styles/settingsItem.css +++ b/apps/cyberstorm-remix/app/styles/settingsItem.css @@ -58,4 +58,18 @@ border-radius: var(--radius-md); background: var(--color-surface-default); } + + @media (width <= 48rem) { + .settings-items__item { + flex-direction: column; + } + + .settings-items__meta { + width: 100%; + } + + .settings-items__content { + width: 100%; + } + } }