chore: address ESLint errors

This commit is contained in:
Danny Avila 2025-06-19 21:58:45 -04:00
parent 5512c55d71
commit f8c8b89f4d
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
6 changed files with 86 additions and 60 deletions

View file

@ -188,7 +188,10 @@ const getUserOwnedEntraGroups = async (accessToken, sub) => {
try {
const graphClient = await createGraphClient(accessToken, sub);
const groupsResponse = await graphClient.api('/me/ownedObjects/microsoft.graph.group').select('id').get();
const groupsResponse = await graphClient
.api('/me/ownedObjects/microsoft.graph.group')
.select('id')
.get();
return (groupsResponse.value || []).map((group) => group.id);
} catch (error) {

View file

@ -60,7 +60,7 @@ describe('GraphApiService', () => {
beforeEach(async () => {
jest.clearAllMocks();
await mongoose.connection.dropDatabase();
// Set up environment variable for People.Read scope
process.env.OPENID_GRAPH_SCOPES = 'User.Read,People.Read,Group.Read.All';

View file

@ -484,7 +484,7 @@ const hasPublicPermission = async ({ resourceType, resourceId, requiredPermissio
// Use public principal to check permissions
const publicPrincipal = [{ principalType: 'public' }];
const entries = await findEntriesByPrincipalsAndResource(
publicPrincipal,
resourceType,
@ -492,7 +492,7 @@ const hasPublicPermission = async ({ resourceType, resourceId, requiredPermissio
);
// Check if any entry has the required permission bits
return entries.some(entry => (entry.permBits & requiredPermissions) === requiredPermissions);
return entries.some((entry) => (entry.permBits & requiredPermissions) === requiredPermissions);
} catch (error) {
logger.error(`[PermissionService.hasPublicPermission] Error: ${error.message}`);
// Re-throw validation errors

View file

@ -41,8 +41,8 @@ export default function GrantAccessDialog({
const {
data: permissionsData,
isLoading: isLoadingPermissions,
error: permissionsError,
// isLoading: isLoadingPermissions,
// error: permissionsError,
} = useGetResourcePermissionsQuery(resourceType, agentDbId!, {
enabled: !!agentDbId,
});

View file

@ -8,7 +8,6 @@ import {
OGDialogClose,
OGDialogContent,
OGDialogTrigger,
Badge,
} from '~/components/ui';
import { cn, removeFocusOutlines } from '~/utils';
import { useToastContext } from '~/Providers';
@ -43,7 +42,10 @@ export default function ManagePermissionsDialog({
} = useGetResourcePermissionsQuery(resourceType, agentDbId, {
enabled: !!agentDbId,
});
const { data: accessRoles, isLoading: rolesLoading } = useGetAccessRolesQuery(resourceType);
const {
data: accessRoles,
// isLoading,
} = useGetAccessRolesQuery(resourceType);
const updatePermissionsMutation = useUpdateResourcePermissionsMutation();
@ -165,11 +167,31 @@ export default function ManagePermissionsDialog({
const totalShares = managedShares.length + (managedIsPublic ? 1 : 0);
const originalTotalShares = currentShares.length + (isPublic ? 1 : 0);
// Check if there's at least one owner (user, group, or public with owner role)
/** Check if there's at least one owner (user, group, or public with owner role) */
const hasAtLeastOneOwner =
managedShares.some((share) => share.accessRoleId === ACCESS_ROLE_IDS.AGENT_OWNER) ||
(managedIsPublic && managedPublicRole === ACCESS_ROLE_IDS.AGENT_OWNER);
let peopleLabel = localize('com_ui_people');
if (managedShares.length === 1) {
peopleLabel = localize('com_ui_person');
}
let buttonAriaLabel = localize('com_ui_manage_permissions_for') + ' agent';
if (agentName != null && agentName !== '') {
buttonAriaLabel = localize('com_ui_manage_permissions_for') + ` "${agentName}"`;
}
let dialogTitle = localize('com_ui_manage_permissions_for') + ' Agent';
if (agentName != null && agentName !== '') {
dialogTitle = localize('com_ui_manage_permissions_for') + ` "${agentName}"`;
}
let publicSuffix = '';
if (managedIsPublic) {
publicSuffix = localize('com_ui_and_public');
}
return (
<OGDialog open={isModalOpen} onOpenChange={setIsModalOpen}>
<OGDialogTrigger asChild>
@ -178,11 +200,7 @@ export default function ManagePermissionsDialog({
'btn btn-neutral border-token-border-light relative h-9 rounded-lg font-medium',
removeFocusOutlines,
)}
aria-label={
agentName != null && agentName !== ''
? localize('com_ui_manage_permissions_for') + ` "${agentName}"`
: localize('com_ui_manage_permissions_for') + ' agent'
}
aria-label={buttonAriaLabel}
type="button"
>
<div className="flex items-center justify-center gap-2 text-blue-500">
@ -197,9 +215,7 @@ export default function ManagePermissionsDialog({
<OGDialogTitle>
<div className="flex items-center gap-2">
<Shield className="h-5 w-5 text-blue-500" />
{agentName != null && agentName !== ''
? localize('com_ui_manage_permissions_for') + ` "${agentName}"`
: localize('com_ui_manage_permissions_for') + ' Agent'}
{dialogTitle}
</div>
</OGDialogTitle>
@ -211,16 +227,16 @@ export default function ManagePermissionsDialog({
{localize('com_ui_current_access')}
</h3>
<p className="text-xs text-text-secondary">
{totalShares === 0
? localize('com_ui_no_users_groups_access')
: localize('com_ui_shared_with_count', {
0: managedShares.length,
1:
managedShares.length === 1
? localize('com_ui_person')
: localize('com_ui_people'),
2: managedIsPublic ? localize('com_ui_and_public') : '',
})}
{(() => {
if (totalShares === 0) {
return localize('com_ui_no_users_groups_access');
}
return localize('com_ui_shared_with_count', {
0: managedShares.length,
1: peopleLabel,
2: publicSuffix,
});
})()}
</p>
</div>
{(managedShares.length > 0 || managedIsPublic) && (
@ -237,34 +253,44 @@ export default function ManagePermissionsDialog({
</div>
</div>
{isLoadingPermissions ? (
<div className="flex items-center justify-center p-8">
<Loader className="h-6 w-6 animate-spin" />
<span className="ml-2 text-sm text-text-secondary">
{localize('com_ui_loading_permissions')}
</span>
</div>
) : managedShares.length > 0 ? (
<div>
<h3 className="mb-3 flex items-center gap-2 text-sm font-medium text-text-primary">
<UserCheck className="h-4 w-4" />
{localize('com_ui_user_group_permissions')} ({managedShares.length})
</h3>
<SelectedPrincipalsList
principles={managedShares}
onRemoveHandler={handleRemoveShare}
availableRoles={accessRoles || []}
onRoleChange={(id, newRole) => handleRoleChange(id, newRole)}
/>
</div>
) : (
<div className="rounded-lg border-2 border-dashed border-border-light p-8 text-center">
<Users className="mx-auto h-8 w-8 text-text-secondary" />
<p className="mt-2 text-sm text-text-secondary">
{localize('com_ui_no_individual_access')}
</p>
</div>
)}
{(() => {
if (isLoadingPermissions) {
return (
<div className="flex items-center justify-center p-8">
<Loader className="h-6 w-6 animate-spin" />
<span className="ml-2 text-sm text-text-secondary">
{localize('com_ui_loading_permissions')}
</span>
</div>
);
}
if (managedShares.length > 0) {
return (
<div>
<h3 className="mb-3 flex items-center gap-2 text-sm font-medium text-text-primary">
<UserCheck className="h-4 w-4" />
{localize('com_ui_user_group_permissions')} ({managedShares.length})
</h3>
<SelectedPrincipalsList
principles={managedShares}
onRemoveHandler={handleRemoveShare}
availableRoles={accessRoles || []}
onRoleChange={(id, newRole) => handleRoleChange(id, newRole)}
/>
</div>
);
}
return (
<div className="rounded-lg border-2 border-dashed border-border-light p-8 text-center">
<Users className="mx-auto h-8 w-8 text-text-secondary" />
<p className="mt-2 text-sm text-text-secondary">
{localize('com_ui_no_individual_access')}
</p>
</div>
);
})()}
<div>
<h3 className="mb-3 text-sm font-medium text-text-primary">

View file

@ -6,7 +6,6 @@ import { Search, X } from 'lucide-react';
import { cn } from '~/utils';
import { Spinner } from '~/components/svg';
import { Skeleton } from '~/components/ui';
import { useLocation } from 'react-router-dom';
import { useLocalize } from '~/hooks';
type SearchPickerProps<TOption extends { key: string }> = {
@ -31,7 +30,6 @@ export function SearchPicker<TOption extends { key: string; value: string }>({
onQueryChange,
query,
label,
inputClassName,
isSmallScreen = false,
placeholder,
resetValueOnHide = false,
@ -39,8 +37,7 @@ export function SearchPicker<TOption extends { key: string; value: string }>({
minQueryLengthForNoResults = 2,
}: SearchPickerProps<TOption>) {
const localize = useLocalize();
const location = useLocation();
const [open, setOpen] = React.useState(false);
const [_open, setOpen] = React.useState(false);
const inputRef = React.useRef<HTMLInputElement>(null);
const combobox = Ariakit.useComboboxStore({
resetValueOnHide,
@ -96,7 +93,7 @@ export function SearchPicker<TOption extends { key: string; value: string }>({
value={query}
// autoSelect
placeholder={placeholder || localize('com_ui_select_options')}
className="m-0 mr-0 w-full rounded-md border-none bg-surface-secondary bg-transparent p-0 py-2 pl-7 pl-9 pr-3 text-sm leading-tight text-text-primary placeholder-text-secondary placeholder-opacity-100 focus:outline-none focus-visible:outline-none group-focus-within:placeholder-text-primary group-hover:placeholder-text-primary"
className="m-0 mr-0 w-full rounded-md border-none bg-transparent p-0 py-2 pl-9 pr-3 text-sm leading-tight text-text-primary placeholder-text-secondary placeholder-opacity-100 focus:outline-none focus-visible:outline-none group-focus-within:placeholder-text-primary group-hover:placeholder-text-primary"
/>
<button
type="button"