mirror of
https://github.com/unraid/api.git
synced 2026-01-04 07:29:48 -06:00
<!-- 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 -->
60 lines
1.6 KiB
Vue
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>
|