Files
api/web/components/ApiKey/PermissionCounter.vue
Eli Bosley 0788756b91 feat: add management page for API keys (#1408)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added ability to update existing API keys, including name,
description, roles, and permissions, through the UI and GraphQL API.
- Introduced a modal-based interface for creating and editing API keys
with improved role and permission selection.
- Added a new API Key Manager page and custom element for centralized
API key management.
- Enhanced API key listing with detailed views, role badges, permission
counters, and copy-to-clipboard functionality.
- Introduced reusable dialog components for consistent modal
experiences.
- Added plugin management capabilities with mutations to add or remove
plugins.
- Added comprehensive support for managing remote access, network URLs,
and API key updates within the GraphQL schema.

- **Bug Fixes**
- Improved error handling and display for API key creation and update
operations.

- **Refactor**
- Centralized API key modal and editing state management using a
dedicated store.
- Updated GraphQL queries and mutations to use reusable fragments for
API key data.
- Removed deprecated or redundant remote access and allowed origins
configuration components and queries.
- Simplified and updated input types for connect settings and remote
access.

- **Tests**
- Added comprehensive tests for API key update logic and improved
coverage for API key loading.

- **Chores**
- Updated configuration files and cleaned up unused schema and component
files.
  - Added new dialog components and centralized exports for dialogs.
- Improved ESLint configuration and import statements for better type
handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-18 11:18:36 -04:00

60 lines
1.6 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue';
import { Badge } from '@unraid/ui';
import { actionVariant } from './actionVariant.js';
const props = withDefaults(
defineProps<{
permissions: { resource: string; actions: string[] }[];
possiblePermissions?: { resource: string; actions: string[] }[];
hideNumber?: boolean;
label?: string;
}>(),
{
label: '',
possiblePermissions: () => [],
hideNumber: false,
}
);
const possibleActions = computed(() => {
if (!props.possiblePermissions) return [];
return Array.from(new Set(props.possiblePermissions.flatMap((p) => p.actions)));
});
const actionCounts = computed(() => {
const actions = possibleActions.value;
const counts: Record<string, number> = {};
for (const action of actions) {
counts[action] = props.permissions.reduce(
(sum, perm) => sum + perm.actions.filter((a) => a === action).length,
0
);
}
return counts;
});
const filteredActions = computed(() => {
return possibleActions.value.filter((action) => actionCounts.value[action] > 0);
});
</script>
<template>
<div class="flex flex-row items-center gap-1">
<span v-if="label">{{ label }}</span>
<template v-if="possibleActions.length">
<Badge
v-for="action in filteredActions"
:key="action"
:variant="actionVariant(action)"
class="text-xs text-muted-foreground"
>
<span v-if="!hideNumber">{{ action }}: {{ actionCounts[action] || 0 }}</span>
<span v-else>{{ action }}</span>
</Badge>
</template>
</div>
</template>