This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit 694e264da50a0118c2bdd680194b7eb687159151
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Fri Feb 27 18:48:36 2026 -0500

    Front-end Access for 4.18.0
---
 .../src/karavan/features/access/AccessPage.css     |  0
 .../src/karavan/features/access/AccessPage.tsx     | 85 +++++++++++++---------
 .../karavan/features/access/roles/RoleModal.tsx    | 18 ++++-
 .../karavan/features/access/roles/RolesTable.tsx   | 20 ++++-
 .../features/access/roles/RolesTableRow.tsx        | 26 ++++++-
 .../features/access/users/ChangePassword.tsx       | 18 ++++-
 .../features/access/users/PasswordModal.tsx        | 18 ++++-
 .../karavan/features/access/users/UserModal.tsx    | 18 ++++-
 .../karavan/features/access/users/UserProfile.tsx  | 18 ++++-
 .../features/access/users/UserProfileTab.tsx       | 16 ++++
 .../karavan/features/access/users/UsersTable.tsx   | 20 ++++-
 .../features/access/users/UsersTableRow.tsx        | 17 ++++-
 12 files changed, 229 insertions(+), 45 deletions(-)

diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/AccessPage.css 
b/karavan-app/src/main/webui/src/karavan/features/access/AccessPage.css
deleted file mode 100644
index e69de29b..00000000
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/AccessPage.tsx 
b/karavan-app/src/main/webui/src/karavan/features/access/AccessPage.tsx
index 3eef0643..2ad6abb3 100644
--- a/karavan-app/src/main/webui/src/karavan/features/access/AccessPage.tsx
+++ b/karavan-app/src/main/webui/src/karavan/features/access/AccessPage.tsx
@@ -1,6 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React, {useEffect, useState} from 'react';
 import {Button, capitalize, Content, Nav, NavItem, NavList, TextInputGroup, 
TextInputGroupMain, TextInputGroupUtilities,} from '@patternfly/react-core';
-import {useAccessStore} from "../../stores/AccessStore";
+import {useAccessStore} from "@stores/AccessStore";
 import {shallow} from "zustand/shallow";
 import {AccessService} from "@services/AccessService";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
@@ -9,7 +25,7 @@ import {RightPanel} from "@shared/ui/RightPanel";
 import SearchIcon from "@patternfly/react-icons/dist/esm/icons/search-icon";
 import TimesIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
 import {UsersTable} from "@features/access/users/UsersTable";
-import {ErrorBoundaryWrapper} from 
"@features/integration/designer/ErrorBoundaryWrapper";
+import {ErrorBoundaryWrapper} from 
"@features/project/designer/ErrorBoundaryWrapper";
 import {RolesTable} from "@features/access/roles/RolesTable";
 import {UserModal} from "./users/UserModal";
 import {RoleModal} from "@features/access/roles/RoleModal";
@@ -33,14 +49,14 @@ export const AccessPage = () => {
 
     function searchInput() {
         return (
-            <TextInputGroup className="search">
+            <TextInputGroup className="search" style={{width:'300px'}}>
                 <TextInputGroupMain
                     value={filter}
                     placeholder='Search'
                     type="text"
                     autoComplete={"off"}
                     autoFocus={true}
-                    icon={<SearchIcon />}
+                    icon={<SearchIcon/>}
                     onChange={(_event, value) => {
                         setFilter(value);
                     }}
@@ -58,24 +74,24 @@ export const AccessPage = () => {
     }
 
     function tools() {
-        return (<div style={{ display: "flex", gap: "8px", alignItems: 
"center" }}>
-                    <Button icon={<RefreshIcon/>}
-                            variant={"link"}
-                            onClick={e => AccessService.refreshAccess()}
-                    />
-                    {searchInput()}
-                    <Button className="dev-action-button"
-                            icon={<PlusIcon/>}
-                            onClick={e => {
-                                setCurrentUser(undefined)
-                                if (activeItem === "users") {
-                                    setShowUserModal(true)
-                                } else {
-                                    setShowRoleModal(true)
-                                }
-                            }}
-                    >Add</Button>
-            </div>);
+        return (<div className="project-files-toolbar" style={{justifyContent: 
"flex-end"}}>
+            <Button icon={<RefreshIcon/>}
+                    variant={"link"}
+                    onClick={e => AccessService.refreshAccess()}
+            />
+            {searchInput()}
+            <Button className="dev-action-button"
+                    icon={<PlusIcon/>}
+                    onClick={e => {
+                        setCurrentUser(undefined)
+                        if (activeItem === "users") {
+                            setShowUserModal(true)
+                        } else {
+                            setShowRoleModal(true)
+                        }
+                    }}
+            >Add</Button>
+        </div>);
     }
 
     function title() {
@@ -90,10 +106,10 @@ export const AccessPage = () => {
                 <NavList>
                     {(getCurrentUser()?.roles?.includes(PLATFORM_ADMIN) ? 
adminMenus : userMenus)
                         .filter(m => []).map((item, i) =>
-                        <NavItem key={item} preventDefault itemId={item} 
isActive={activeItem === item} to="#">
-                            {capitalize(item?.toString())}
-                        </NavItem>
-                    )}
+                            <NavItem key={item} preventDefault itemId={item} 
isActive={activeItem === item} to="#">
+                                {capitalize(item?.toString())}
+                            </NavItem>
+                        )}
                 </NavList>
             </Nav>
         )
@@ -103,16 +119,19 @@ export const AccessPage = () => {
         <RightPanel
             title={title()}
             toolsStart={getNavigation()}
-            tools={tools()}
+            tools={undefined}
             mainPanel={
                 <div className="right-panel-card">
                     <ErrorBoundaryWrapper key='info' onError={error => 
console.error(error)}>
-                        {activeItem === 'users' && <UsersTable/>}
-                        {activeItem === 'roles' && <RolesTable/>}
-                        {activeItem === 'profile' && <UserProfileTab/>}
-                        {showUserModal && <UserModal/>}
-                        {showRoleModal && <RoleModal/>}
-                        {showPasswordModal && <PasswordModal/>}
+                        <div style={{display: 'flex', flexDirection: 'column', 
height: '100%'}}>
+                            {activeItem !== 'profile' && tools()}
+                            {activeItem === 'users' && <UsersTable/>}
+                            {activeItem === 'roles' && <RolesTable/>}
+                            {activeItem === 'profile' && <UserProfileTab/>}
+                            {showUserModal && <UserModal/>}
+                            {showRoleModal && <RoleModal/>}
+                            {showPasswordModal && <PasswordModal/>}
+                        </div>
                     </ErrorBoundaryWrapper>
                 </div>
             }
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/roles/RoleModal.tsx 
b/karavan-app/src/main/webui/src/karavan/features/access/roles/RoleModal.tsx
index d6df79cc..cc7987ff 100644
--- a/karavan-app/src/main/webui/src/karavan/features/access/roles/RoleModal.tsx
+++ b/karavan-app/src/main/webui/src/karavan/features/access/roles/RoleModal.tsx
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React, {useEffect} from 'react';
 import {Alert, Button, Content, Form, FormAlert, Modal, ModalBody, 
ModalFooter, ModalHeader, ModalVariant,} from '@patternfly/react-core';
 import {SubmitHandler, useForm} from "react-hook-form";
@@ -5,7 +21,7 @@ import {AxiosResponse} from "axios";
 import {AccessRole} from "../../../models/AccessModels";
 import {useAccessStore} from "../../../stores/AccessStore";
 import {useFormUtil} from "@util/useFormUtil";
-import {EventBus} from "@features/integration/designer/utils/EventBus";
+import {EventBus} from "@features/project/designer/utils/EventBus";
 import {shallow} from "zustand/shallow";
 import {AccessApi} from "../../../api/AccessApi";
 import {AccessService} from "@services/AccessService";
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/roles/RolesTable.tsx 
b/karavan-app/src/main/webui/src/karavan/features/access/roles/RolesTable.tsx
index f06b76e7..c8200518 100644
--- 
a/karavan-app/src/main/webui/src/karavan/features/access/roles/RolesTable.tsx
+++ 
b/karavan-app/src/main/webui/src/karavan/features/access/roles/RolesTable.tsx
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React, {useState} from 'react';
 import {Bullseye, EmptyState, EmptyStateVariant, Spinner} from 
'@patternfly/react-core';
 import '../AccessPage.css';
@@ -32,8 +48,8 @@ export function RolesTable() {
 
     const conts = roles.filter(role =>
         role.name?.toLowerCase().includes(filter)
-        || role.name.toLowerCase().includes(filter)
-        || role.name.toLowerCase().includes(filter)
+        || role.name?.toLowerCase().includes(filter)
+        || role.name?.toLowerCase().includes(filter)
     ).sort((a, b) => a.name.localeCompare(b.name));
     return (
         <OuterScrollContainer>
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/roles/RolesTableRow.tsx
 
b/karavan-app/src/main/webui/src/karavan/features/access/roles/RolesTableRow.tsx
index 66fdbd9f..c26653ac 100644
--- 
a/karavan-app/src/main/webui/src/karavan/features/access/roles/RolesTableRow.tsx
+++ 
b/karavan-app/src/main/webui/src/karavan/features/access/roles/RolesTableRow.tsx
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React, {useState} from 'react';
 import {Button, capitalize, Content, Label} from '@patternfly/react-core';
 import {Tbody, Td, Tr} from "@patternfly/react-table";
@@ -7,6 +23,8 @@ import {shallow} from "zustand/shallow";
 import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
 import {ShieldAltIcon, UsersIcon} from "@patternfly/react-icons";
 import {ModalConfirmation} from "@shared/ui/ModalConfirmation";
+import {AccessApi} from "@api/AccessApi";
+import {AccessService} from "@services/AccessService";
 
 interface Props {
     index: number
@@ -22,7 +40,11 @@ export function RolesTableRow(props: Props) {
     const {role} = props;
 
     function executeAction() {
-
+        if (command === 'delete') {
+            AccessApi.deleteRole(role.name, result => {
+                AccessService.refreshAccess();
+            });
+        }
         setShowConfirmation(false);
     }
 
@@ -39,7 +61,7 @@ export function RolesTableRow(props: Props) {
         }
     }
 
-    const usersWithRole = users.filter(user => user.roles.includes(role.name))
+    const usersWithRole = users.filter(user => user.roles?.includes(role.name))
     const isBuildInRole = [PLATFORM_DEVELOPER, PLATFORM_USER, 
PLATFORM_ADMIN].includes(role?.name);
     const canBeDeleted = !isBuildInRole && usersWithRole.length === 0;
     return (
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/users/ChangePassword.tsx
 
b/karavan-app/src/main/webui/src/karavan/features/access/users/ChangePassword.tsx
index ed420a48..dc0fc670 100644
--- 
a/karavan-app/src/main/webui/src/karavan/features/access/users/ChangePassword.tsx
+++ 
b/karavan-app/src/main/webui/src/karavan/features/access/users/ChangePassword.tsx
@@ -1,10 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React, {useEffect} from 'react';
 import {Alert, Button, Card, CardBody, CardFooter, CardHeader, Content, Form, 
FormAlert, FormGroup, FormHelperText, HelperText, HelperTextItem,} from 
'@patternfly/react-core';
 import {SubmitHandler, useForm} from "react-hook-form";
 import {AxiosResponse} from "axios";
 import {AccessPassword} from "../../../models/AccessModels";
 import {useFormUtil} from "@util/useFormUtil";
-import {EventBus} from "@features/integration/designer/utils/EventBus";
+import {EventBus} from "@features/project/designer/utils/EventBus";
 import {AuthApi} from "@api/auth/AuthApi";
 
 
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/users/PasswordModal.tsx
 
b/karavan-app/src/main/webui/src/karavan/features/access/users/PasswordModal.tsx
index 7d70f759..8a4959b5 100644
--- 
a/karavan-app/src/main/webui/src/karavan/features/access/users/PasswordModal.tsx
+++ 
b/karavan-app/src/main/webui/src/karavan/features/access/users/PasswordModal.tsx
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React, {useEffect} from 'react';
 import {
     Alert,
@@ -19,7 +35,7 @@ import {SubmitHandler, useForm} from "react-hook-form";
 import {AxiosResponse} from "axios";
 import {useAccessStore} from "../../../stores/AccessStore";
 import {useFormUtil} from "@util/useFormUtil";
-import {EventBus} from "@features/integration/designer/utils/EventBus";
+import {EventBus} from "@features/project/designer/utils/EventBus";
 import {shallow} from "zustand/shallow";
 import {AccessPassword} from "@models/AccessModels";
 import {AccessApi} from "@api/AccessApi";
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/users/UserModal.tsx 
b/karavan-app/src/main/webui/src/karavan/features/access/users/UserModal.tsx
index 332e9f64..5744f633 100644
--- a/karavan-app/src/main/webui/src/karavan/features/access/users/UserModal.tsx
+++ b/karavan-app/src/main/webui/src/karavan/features/access/users/UserModal.tsx
@@ -1,10 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React, {useEffect} from 'react';
 import {Alert, Button, Content, Form, FormAlert, FormGroup, Modal, ModalBody, 
ModalFooter, ModalHeader, ModalVariant, TextInput,} from 
'@patternfly/react-core';
 import {SubmitHandler, useForm} from "react-hook-form";
 import {AxiosResponse} from "axios";
 import {useAccessStore} from "../../../stores/AccessStore";
 import {useFormUtil} from "@util/useFormUtil";
-import {EventBus} from "@features/integration/designer/utils/EventBus";
+import {EventBus} from "@features/project/designer/utils/EventBus";
 import {shallow} from "zustand/shallow";
 import {AccessApi} from "../../../api/AccessApi";
 import {getCurrentUser} from "@api/auth/AuthApi";
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/users/UserProfile.tsx 
b/karavan-app/src/main/webui/src/karavan/features/access/users/UserProfile.tsx
index c0387543..1f9272e0 100644
--- 
a/karavan-app/src/main/webui/src/karavan/features/access/users/UserProfile.tsx
+++ 
b/karavan-app/src/main/webui/src/karavan/features/access/users/UserProfile.tsx
@@ -1,10 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React, {useEffect} from 'react';
 import {Alert, Button, Card, CardBody, CardFooter, CardHeader, Content, Form, 
FormAlert, FormGroup, TextInput,} from '@patternfly/react-core';
 import {SubmitHandler, useForm} from "react-hook-form";
 import {AxiosResponse} from "axios";
 import {AccessUser} from "../../../models/AccessModels";
 import {useFormUtil} from "@util/useFormUtil";
-import {EventBus} from "@features/integration/designer/utils/EventBus";
+import {EventBus} from "@features/project/designer/utils/EventBus";
 import {AccessApi} from "../../../api/AccessApi";
 import {AuthApi, getCurrentUser} from "@api/auth/AuthApi";
 
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/users/UserProfileTab.tsx
 
b/karavan-app/src/main/webui/src/karavan/features/access/users/UserProfileTab.tsx
index 785fbf85..9f36d4f8 100644
--- 
a/karavan-app/src/main/webui/src/karavan/features/access/users/UserProfileTab.tsx
+++ 
b/karavan-app/src/main/webui/src/karavan/features/access/users/UserProfileTab.tsx
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React from 'react';
 import UserProfile from "@features/access/users/UserProfile";
 import {ChangePassword} from "@features/access/users/ChangePassword";
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/users/UsersTable.tsx 
b/karavan-app/src/main/webui/src/karavan/features/access/users/UsersTable.tsx
index d1436f17..db763e3e 100644
--- 
a/karavan-app/src/main/webui/src/karavan/features/access/users/UsersTable.tsx
+++ 
b/karavan-app/src/main/webui/src/karavan/features/access/users/UsersTable.tsx
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React, {useState} from 'react';
 import {Bullseye, EmptyState, EmptyStateVariant, Spinner} from 
'@patternfly/react-core';
 import '../AccessPage.css';
@@ -32,8 +48,8 @@ export function UsersTable() {
 
     const conts = users.filter(user =>
         user.username?.toLowerCase().includes(filter)
-        || user.firstName.toLowerCase().includes(filter)
-        || user.lastName.toLowerCase().includes(filter)
+        || user.firstName?.toLowerCase().includes(filter)
+        || user.lastName?.toLowerCase().includes(filter)
     ).sort((a, b) => a.username.localeCompare(b.username));
     return (
         <OuterScrollContainer>
diff --git 
a/karavan-app/src/main/webui/src/karavan/features/access/users/UsersTableRow.tsx
 
b/karavan-app/src/main/webui/src/karavan/features/access/users/UsersTableRow.tsx
index 7b35dc51..f1dacf4c 100644
--- 
a/karavan-app/src/main/webui/src/karavan/features/access/users/UsersTableRow.tsx
+++ 
b/karavan-app/src/main/webui/src/karavan/features/access/users/UsersTableRow.tsx
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 import React, {useState} from 'react';
 import {Button, capitalize, Label, Switch} from '@patternfly/react-core';
 import {Tbody, Td, Tr} from "@patternfly/react-table";
@@ -39,7 +55,6 @@ export function UsersTableRow(props: Props) {
                 AccessService.refreshAccess();
             });
         }
-
         setShowConfirmation(false);
     }
 

Reply via email to