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}
- />
-
+
+
{
+ 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%;
+ }
+ }
}