rename proyecto a Alpha, refactor imports a components/ui, fix types en stores

This commit is contained in:
Ricardo Gonzalez
2026-05-23 17:38:15 -05:00
parent 002d8f06d3
commit 72662852bf
24 changed files with 347 additions and 59 deletions
+21
View File
@@ -13,6 +13,7 @@
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"dexie": "^4.0.4", "dexie": "^4.0.4",
"dnd-kit-vue": "^0.0.2",
"lucide-vue-next": "^1.0.0", "lucide-vue-next": "^1.0.0",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"reka-ui": "^2.9.8", "reka-ui": "^2.9.8",
@@ -89,6 +90,16 @@
"@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
"@dnd-kit/abstract": ["@dnd-kit/abstract@0.1.21", "", { "dependencies": { "@dnd-kit/geometry": "^0.1.21", "@dnd-kit/state": "^0.1.21", "tslib": "^2.6.2" } }, "sha512-6sJut6/D21xPIK8EFMu+JJeF+fBCOmQKN1BRpeUYFi5m9P1CJpTYbBwfI107h7PHObI6a5bsckiKkRpF2orHpw=="],
"@dnd-kit/collision": ["@dnd-kit/collision@0.1.21", "", { "dependencies": { "@dnd-kit/abstract": "^0.1.21", "@dnd-kit/geometry": "^0.1.21", "tslib": "^2.6.2" } }, "sha512-9AJ4NbuwGDexxMCZXZyKdNQhbAe93p6C6IezQaDaWmdCqZHMHmC3+ul7pGefBQfOooSarGwIf8Bn182o9SMa1A=="],
"@dnd-kit/dom": ["@dnd-kit/dom@0.1.21", "", { "dependencies": { "@dnd-kit/abstract": "^0.1.21", "@dnd-kit/collision": "^0.1.21", "@dnd-kit/geometry": "^0.1.21", "@dnd-kit/state": "^0.1.21", "tslib": "^2.6.2" } }, "sha512-6UDc1y2Y3oLQKArGlgCrZxz5pdEjRSiQujXOn5JdbuWvKqTdUR5RTYDeicr+y2sVm3liXjTqs3WlUoV+eqhqUQ=="],
"@dnd-kit/geometry": ["@dnd-kit/geometry@0.1.21", "", { "dependencies": { "@dnd-kit/state": "^0.1.21", "tslib": "^2.6.2" } }, "sha512-Tir97wNJbopN2HgkD7AjAcoB3vvrVuUHvwdPALmNDUH0fWR637c4MKQ66YjjZAbUEAR8KL6mlDiHH4MzTLd7CQ=="],
"@dnd-kit/state": ["@dnd-kit/state@0.1.21", "", { "dependencies": { "@preact/signals-core": "^1.10.0", "tslib": "^2.6.2" } }, "sha512-pdhntEPvn/QttcF295bOJpWiLsRqA/Iczh1ODOJUxGiR+E4GkYVz9VapNNm9gDq6ST0tr/e1Q2xBztUHlJqQgA=="],
"@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.67.0", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^17.2.1", "eciesjs": "^0.4.10", "enquirer": "^2.4.1", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.4", "which": "^4.0.0", "yocto-spinner": "^1.1.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-KBfIx5OrAG6giqSkHCkQWynZmT47XkSTuuYIcvjHxlKoVRlYbxNrJmyIPaefnszU8MCvMwrrB+viJQzPqzgpcg=="], "@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.67.0", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^17.2.1", "eciesjs": "^0.4.10", "enquirer": "^2.4.1", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.4", "which": "^4.0.0", "yocto-spinner": "^1.1.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-KBfIx5OrAG6giqSkHCkQWynZmT47XkSTuuYIcvjHxlKoVRlYbxNrJmyIPaefnszU8MCvMwrrB+viJQzPqzgpcg=="],
"@ecies/ciphers": ["@ecies/ciphers@0.2.6", "", { "peerDependencies": { "@noble/ciphers": "^1.0.0" } }, "sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g=="], "@ecies/ciphers": ["@ecies/ciphers@0.2.6", "", { "peerDependencies": { "@noble/ciphers": "^1.0.0" } }, "sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g=="],
@@ -213,6 +224,8 @@
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
"@preact/signals-core": ["@preact/signals-core@1.14.2", "", {}, "sha512-RZHdBj9ZF4n40Rp4jS052EHHjBWf96P9oNdXPfhQTovCuWY9iQn3Gq+gOTJSgBO9A/JBuPfMOWsSX/lIU9Pc/A=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.4", "", { "os": "android", "cpu": "arm" }, "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ=="], "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.4", "", { "os": "android", "cpu": "arm" }, "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ=="],
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.60.4", "", { "os": "android", "cpu": "arm64" }, "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw=="], "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.60.4", "", { "os": "android", "cpu": "arm64" }, "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw=="],
@@ -501,6 +514,8 @@
"diff": ["diff@8.0.4", "", {}, "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw=="], "diff": ["diff@8.0.4", "", {}, "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw=="],
"dnd-kit-vue": ["dnd-kit-vue@0.0.2", "", { "dependencies": { "@dnd-kit/abstract": "^0.1.19", "@dnd-kit/dom": "^0.1.19", "@dnd-kit/state": "^0.1.19", "@vueuse/core": "^13.4.0", "reka-ui": "^2.3.1" }, "peerDependencies": { "vue": "^3.3.0" } }, "sha512-2ZQfqTulZI7vqFiYscV7VMQRXSEryjanlaCY5BvkDf5i+whEAvOKSckyBa6SK8LCPaF5f/IIcUhfh6TnbaWq3A=="],
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
@@ -1117,6 +1132,8 @@
"css/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "css/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
"dnd-kit-vue/@vueuse/core": ["@vueuse/core@13.9.0", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "13.9.0", "@vueuse/shared": "13.9.0" }, "peerDependencies": { "vue": "^3.5.0" } }, "sha512-ts3regBQyURfCE2BcytLqzm8+MmLlo5Ln/KLoxDVcsZ2gzIwVNnQpQOL/UKV8alUqjSZOlpFZcRNsLRqj+OzyA=="],
"dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"eslint/ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], "eslint/ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="],
@@ -1155,6 +1172,10 @@
"cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"dnd-kit-vue/@vueuse/core/@vueuse/metadata": ["@vueuse/metadata@13.9.0", "", {}, "sha512-1AFRvuiGphfF7yWixZa0KwjYH8ulyjDCC0aFgrGRz8+P4kvDFSdXLVfTk5xAN9wEuD1J6z4/myMoYbnHoX07zg=="],
"dnd-kit-vue/@vueuse/core/@vueuse/shared": ["@vueuse/shared@13.9.0", "", { "peerDependencies": { "vue": "^3.5.0" } }, "sha512-e89uuTLMh0U5cZ9iDpEI2senqPGfbPRTHM/0AaQkcxnpqjkZqDYP8rpfm7edOz8s+pOCOROEy1PIveSW8+fL5g=="],
"eslint/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], "eslint/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
"eslint/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], "eslint/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="],
+1 -1
View File
@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Alpha — KAPPA Hub</title> <title>Alpha</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
+2 -1
View File
@@ -1,5 +1,5 @@
{ {
"name": "kappa-hub", "name": "alpha",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"type": "module", "type": "module",
@@ -18,6 +18,7 @@
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"dexie": "^4.0.4", "dexie": "^4.0.4",
"dnd-kit-vue": "^0.0.2",
"lucide-vue-next": "^1.0.0", "lucide-vue-next": "^1.0.0",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"reka-ui": "^2.9.8", "reka-ui": "^2.9.8",
+1 -1
View File
@@ -49,7 +49,7 @@ function setTab(tab: string) {
</div> </div>
<div class="grid flex-1 text-left text-sm leading-tight"> <div class="grid flex-1 text-left text-sm leading-tight">
<span class="truncate font-semibold">Alpha</span> <span class="truncate font-semibold">Alpha</span>
<span class="truncate text-xs">KAPPA Hub</span> <span class="truncate text-xs">Alpha</span>
</div> </div>
</SidebarMenuButton> </SidebarMenuButton>
</SidebarMenuItem> </SidebarMenuItem>
+4 -16
View File
@@ -22,28 +22,16 @@ import {
SidebarContent, SidebarContent,
SidebarFooter, SidebarFooter,
SidebarHeader, SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar" } from "@/components/ui/sidebar"
</script> </script>
<template> <template>
<Sidebar collapsible="offcanvas"> <Sidebar collapsible="offcanvas">
<SidebarHeader> <SidebarHeader>
<SidebarMenu> <div class="flex items-center gap-2 px-3 py-2">
<SidebarMenuItem> <IconInnerShadowTop class="size-5" />
<SidebarMenuButton <span class="text-base font-semibold">Alpha</span>
as-child </div>
class="data-[slot=sidebar-menu-button]:!p-1.5"
>
<a href="#">
<IconInnerShadowTop class="!size-5" />
<span class="text-base font-semibold">KAPPA Hub</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarHeader> </SidebarHeader>
<SidebarContent> <SidebarContent>
<NavMain /> <NavMain />
@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ChartConfig } from "@/registry/new-york-v4/ui/chart" import { ref, computed } from "vue"
import type { ChartConfig } from "@/components/ui/chart"
// import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts" // import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts"
import { VisArea, VisAxis, VisLine, VisXYContainer } from "@unovis/vue" import { VisArea, VisAxis, VisLine, VisXYContainer } from "@unovis/vue"
@@ -9,7 +10,7 @@ import {
CardDescription, CardDescription,
CardHeader, CardHeader,
CardTitle, CardTitle,
} from "@/registry/new-york-v4/ui/card" } from "@/components/ui/card"
import { import {
ChartContainer, ChartContainer,
@@ -18,14 +19,14 @@ import {
ChartTooltip, ChartTooltip,
ChartTooltipContent, ChartTooltipContent,
componentToString, componentToString,
} from "@/registry/new-york-v4/ui/chart" } from "@/components/ui/chart"
import { import {
Select, Select,
SelectContent, SelectContent,
SelectItem, SelectItem,
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "@/registry/new-york-v4/ui/select" } from "@/components/ui/select"
const description = "An interactive area chart" const description = "An interactive area chart"
@@ -257,7 +258,7 @@ const filterRange = computed(() => {
<ChartTooltip /> <ChartTooltip />
<ChartCrosshair <ChartCrosshair
:template="componentToString(chartConfig, ChartTooltipContent, { :template="componentToString(chartConfig, ChartTooltipContent, {
labelFormatter: (d) => { labelFormatter: (d: number) => {
return new Date(d).toLocaleDateString('en-US', { return new Date(d).toLocaleDateString('en-US', {
month: 'short', month: 'short',
day: 'numeric', day: 'numeric',
+10 -9
View File
@@ -15,6 +15,7 @@ export const schema = z.object({
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import { h, ref, computed } from "vue"
import type { import type {
ColumnDef, ColumnDef,
ColumnFiltersState, ColumnFiltersState,
@@ -43,10 +44,10 @@ import {
useVueTable, useVueTable,
} from "@tanstack/vue-table" } from "@tanstack/vue-table"
import { DragDropProvider } from "dnd-kit-vue" import { DragDropProvider } from "dnd-kit-vue"
import { Badge } from "@/registry/new-york-v4/ui/badge" import { Badge } from "@/components/ui/badge"
import { Button } from "@/registry/new-york-v4/ui/button" import { Button } from "@/components/ui/button"
import { Checkbox } from "@/registry/new-york-v4/ui/checkbox" import { Checkbox } from "@/components/ui/checkbox"
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuCheckboxItem, DropdownMenuCheckboxItem,
@@ -54,16 +55,16 @@ import {
DropdownMenuItem, DropdownMenuItem,
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu" } from "@/components/ui/dropdown-menu"
import { Label } from "@/registry/new-york-v4/ui/label" import { Label } from "@/components/ui/label"
import { import {
Select, Select,
SelectContent, SelectContent,
SelectItem, SelectItem,
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "@/registry/new-york-v4/ui/select" } from "@/components/ui/select"
import { import {
Table, Table,
TableBody, TableBody,
@@ -71,14 +72,14 @@ import {
TableHead, TableHead,
TableHeader, TableHeader,
TableRow, TableRow,
} from "@/registry/new-york-v4/ui/table" } from "@/components/ui/table"
import { import {
Tabs, Tabs,
TabsContent, TabsContent,
TabsList, TabsList,
TabsTrigger, TabsTrigger,
} from "@/registry/new-york-v4/ui/tabs" } from "@/components/ui/tabs"
const props = defineProps<{ const props = defineProps<{
data: TableData[] data: TableData[]
@@ -108,7 +109,7 @@ const columns: ColumnDef<TableData>[] = [
{ {
id: "select", id: "select",
header: ({ table }) => h(Checkbox, { header: ({ table }) => h(Checkbox, {
"modelValue": table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && "indeterminate"), "modelValue": table.getIsAllPageRowsSelected(),
"onUpdate:modelValue": value => table.toggleAllPageRowsSelected(!!value), "onUpdate:modelValue": value => table.toggleAllPageRowsSelected(!!value),
"aria-label": "Select all", "aria-label": "Select all",
}), }),
+1 -1
View File
@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { IconGripVertical } from "@tabler/icons-vue" import { IconGripVertical } from "@tabler/icons-vue"
import { useSortableContext } from "dnd-kit-vue" import { useSortableContext } from "dnd-kit-vue"
import { Button } from "@/registry/new-york-v4/ui/button" import { Button } from "@/components/ui/button"
const { handleRef, sortable } = useSortableContext() const { handleRef, sortable } = useSortableContext()
</script> </script>
+1 -1
View File
@@ -7,7 +7,7 @@ import { useSortable } from "dnd-kit-vue"
import { import {
TableCell, TableCell,
TableRow, TableRow,
} from "@/registry/new-york-v4/ui/table" } from "@/components/ui/table"
const props = defineProps<{ row: Row<z.infer<typeof schema>>, index: number }>() const props = defineProps<{ row: Row<z.infer<typeof schema>>, index: number }>()
+3 -3
View File
@@ -11,7 +11,7 @@ import {
Avatar, Avatar,
AvatarFallback, AvatarFallback,
AvatarImage, AvatarImage,
} from "@/registry/new-york-v4/ui/avatar" } from "@/components/ui/avatar"
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@@ -20,13 +20,13 @@ import {
DropdownMenuLabel, DropdownMenuLabel,
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu" } from "@/components/ui/dropdown-menu"
import { import {
SidebarMenu, SidebarMenu,
SidebarMenuButton, SidebarMenuButton,
SidebarMenuItem, SidebarMenuItem,
useSidebar, useSidebar,
} from "@/registry/new-york-v4/ui/sidebar" } from "@/components/ui/sidebar"
interface User { interface User {
name: string name: string
+2 -2
View File
@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { IconTrendingDown, IconTrendingUp } from "@tabler/icons-vue" import { IconTrendingDown, IconTrendingUp } from "@tabler/icons-vue"
import { Badge } from "@/registry/new-york-v4/ui/badge" import { Badge } from "@/components/ui/badge"
import { import {
Card, Card,
CardAction, CardAction,
@@ -9,7 +9,7 @@ import {
CardFooter, CardFooter,
CardHeader, CardHeader,
CardTitle, CardTitle,
} from "@/registry/new-york-v4/ui/card" } from "@/components/ui/card"
</script> </script>
<template> <template>
@@ -0,0 +1,22 @@
<script setup lang="ts">
export interface ChartConfig {
[key: string]: {
label: string
color?: string
}
}
export const componentToString = () => ""
</script>
<script setup lang="ts">
defineProps<{
config: ChartConfig
}>()
</script>
<template>
<div>
<slot />
</div>
</template>
+7
View File
@@ -0,0 +1,7 @@
export type { ChartConfig } from "./ChartContainer.vue"
export const componentToString = (config: unknown, _component: unknown, _options: unknown) => ""
export const ChartContainer = { name: "ChartContainer" }
export const ChartCrosshair = { name: "ChartCrosshair", template: "" }
export const ChartLegendContent = { name: "ChartLegendContent" }
export const ChartTooltip = { name: "ChartTooltip" }
export const ChartTooltipContent = { name: "ChartTooltipContent" }
+20
View File
@@ -0,0 +1,20 @@
<script setup lang="ts">
defineProps<{
modelValue?: boolean
'onUpdate:modelValue'?: (value: boolean) => void
ariaLabel?: string
disabled?: boolean
checked?: boolean
}>()
</script>
<template>
<input
type="checkbox"
:checked="modelValue || checked"
:disabled="disabled"
:aria-label="ariaLabel"
@change="(e) => $emit('update:modelValue', (e.target as HTMLInputElement).checked)"
class="h-4 w-4 rounded border-gray-300"
/>
</template>
+1
View File
@@ -0,0 +1 @@
export { default as Checkbox } from "./Checkbox.vue"
+11
View File
@@ -0,0 +1,11 @@
<script setup lang="ts">
defineProps<{
for?: string
}>()
</script>
<template>
<label>
<slot />
</label>
</template>
+1
View File
@@ -0,0 +1 @@
export { default as Label } from "./Label.vue"
+181
View File
@@ -0,0 +1,181 @@
import { ref } from "vue"
import { kappa } from "@/services/kappa-api"
import type {
KappaInitiative,
KappaUserStory,
KappaLogbookEntry,
KappaPlanningEntry,
KappaBusinessRule,
KappaRequirement,
} from "@/types/kappa"
export interface SearchResult {
type: "initiative" | "userstory" | "logbook" | "planning" | "businessrule" | "requirement"
id: number
title: string
description?: string
projectId?: number
projectName?: string
}
export function useSearch() {
const results = ref<SearchResult[]>([])
const loading = ref(false)
const error = ref<string | null>(null)
async function search(query: string) {
if (!query.trim()) {
results.value = []
return
}
loading.value = true
error.value = null
try {
const allResults: SearchResult[] = []
const initiativeResult = await Promise.allSettled([kappa.getInitiatives()])
if (initiativeResult[0].status === "fulfilled") {
const data = initiativeResult[0].value as KappaInitiative[]
const items = Array.isArray(data) ? data : (data as { results?: KappaInitiative[] }).results ?? []
items.forEach((item: KappaInitiative) => {
if (matchesQuery(item.name || item.initiative_name || "", query) ||
matchesQuery(item.key || "", query) ||
matchesQuery(item.description || "", query)) {
allResults.push({
type: "initiative",
id: item.id,
title: item.name || item.initiative_name || `Project ${item.id}`,
description: item.description,
projectId: item.id,
projectName: item.name || item.initiative_name,
})
}
})
}
const storyResult = await Promise.allSettled([kappa.getUserStories()])
if (storyResult[0].status === "fulfilled") {
const data = storyResult[0].value as KappaUserStory[]
const items = Array.isArray(data) ? data : (data as { results?: KappaUserStory[] }).results ?? []
items.forEach((item: KappaUserStory) => {
if (matchesQuery(item.title, query) ||
matchesQuery(item.code || "", query) ||
matchesQuery(item.description || "", query)) {
allResults.push({
type: "userstory",
id: item.id || Math.random(),
title: item.title,
description: item.description,
projectId: typeof item.initiative === "number" ? item.initiative : undefined,
})
}
})
}
const logResult = await Promise.allSettled([kappa.getLogbooks()])
if (logResult[0].status === "fulfilled") {
const data = logResult[0].value as KappaLogbookEntry[]
const items = Array.isArray(data) ? data : (data as { results?: KappaLogbookEntry[] }).results ?? []
items.forEach((item: KappaLogbookEntry) => {
if (matchesQuery(item.description, query)) {
allResults.push({
type: "logbook",
id: item.id || Math.random(),
title: item.description.slice(0, 80),
description: item.description,
projectId: typeof item.initiative === "number" ? item.initiative : undefined,
})
}
})
}
const planResult = await Promise.allSettled([kappa.getPlannings()])
if (planResult[0].status === "fulfilled") {
const data = planResult[0].value as KappaPlanningEntry[]
const items = Array.isArray(data) ? data : (data as { results?: KappaPlanningEntry[] }).results ?? []
items.forEach((item: KappaPlanningEntry) => {
if (matchesQuery(item.description, query) ||
matchesQuery(item.responsible || "", query)) {
allResults.push({
type: "planning",
id: item.id || Math.random(),
title: item.description.slice(0, 80),
description: item.description,
projectId: typeof item.initiative === "number" ? item.initiative : undefined,
})
}
})
}
const ruleResult = await Promise.allSettled([kappa.getBusinessRules()])
if (ruleResult[0].status === "fulfilled") {
const data = ruleResult[0].value as KappaBusinessRule[]
const items = Array.isArray(data) ? data : (data as { results?: KappaBusinessRule[] }).results ?? []
items.forEach((item: KappaBusinessRule) => {
if (matchesQuery(item.name, query) ||
matchesQuery(item.description, query)) {
allResults.push({
type: "businessrule",
id: Math.random(),
title: item.name,
description: item.description,
projectId: typeof item.initiative === "number" ? item.initiative : undefined,
})
}
})
}
const reqResult = await Promise.allSettled([kappa.getRequirements()])
if (reqResult[0].status === "fulfilled") {
const data = reqResult[0].value as KappaRequirement[]
const items = Array.isArray(data) ? data : (data as { results?: KappaRequirement[] }).results ?? []
items.forEach((item: KappaRequirement) => {
if (matchesQuery(item.name || item.name_requirement || "", query) ||
matchesQuery(item.description, query)) {
allResults.push({
type: "requirement",
id: Math.random(),
title: item.name || item.name_requirement || "Requirement",
description: item.description,
projectId: typeof item.initiative === "number" ? item.initiative : undefined,
})
}
})
}
results.value = allResults
} catch (e: any) {
error.value = e.message
results.value = []
} finally {
loading.value = false
}
}
function matchesQuery(text: string, query: string): boolean {
return text.toLowerCase().includes(query.toLowerCase())
}
function clearResults() {
results.value = []
}
return {
results,
loading,
error,
search,
clearResults,
}
}
export const typeColors: Record<SearchResult["type"], { bg: string; text: string; label: string }> = {
initiative: { bg: "bg-blue-100 dark:bg-blue-900", text: "text-blue-700 dark:text-blue-300", label: "Project" },
userstory: { bg: "bg-green-100 dark:bg-green-900", text: "text-green-700 dark:text-green-300", label: "User Story" },
logbook: { bg: "bg-purple-100 dark:bg-purple-900", text: "text-purple-700 dark:text-purple-300", label: "Logbook" },
planning: { bg: "bg-orange-100 dark:bg-orange-900", text: "text-orange-700 dark:text-orange-300", label: "Planning" },
businessrule: { bg: "bg-red-100 dark:bg-red-900", text: "text-red-700 dark:text-red-300", label: "Rule" },
requirement: { bg: "bg-yellow-100 dark:bg-yellow-900", text: "text-yellow-700 dark:text-yellow-300", label: "Req" },
}
+16 -1
View File
@@ -13,6 +13,21 @@
"templates": "Templates" "templates": "Templates"
}, },
"siteHeader": { "siteHeader": {
"title": "Dashboard" "title": "Dashboard",
"search": "Search...",
"searchDoc": "Search documentation...",
"searching": "Searching...",
"noResults": "No results found"
},
"settings": {
"title": "Settings",
"language": "Language",
"theme": "Theme",
"light": "Light",
"dark": "Dark",
"system": "System",
"about": "About",
"documentation": "Documentation",
"logout": "Log out"
} }
} }
+26 -11
View File
@@ -1,18 +1,33 @@
{ {
"nav": { "nav": {
"quickCreate": "Crear proyecto", "quickCreate": "Crear proyecto",
"dashboard": "Dashboard", "dashboard": "Tablero",
"projects": "Projects", "projects": "Proyectos",
"lifecycle": "Lifecycle", "lifecycle": "Ciclo de vida",
"analytics": "Analytics", "analytics": "Analíticas",
"team": "Team", "team": "Equipo",
"documents": "Documents", "documents": "Documentos",
"dataLibrary": "Data Library", "dataLibrary": "Biblioteca",
"reports": "Reports", "reports": "Reportes",
"wordAssistant": "Word Assistant", "wordAssistant": "Asistente Word",
"templates": "Templates" "templates": "Plantillas"
}, },
"siteHeader": { "siteHeader": {
"title": "Dashboard" "title": "Tablero",
"search": "Buscar...",
"searchDoc": "Buscar documentación...",
"searching": "Buscando...",
"noResults": "No se encontraron resultados"
},
"settings": {
"title": "Configuración",
"language": "Idioma",
"theme": "Tema",
"light": "Claro",
"dark": "Oscuro",
"system": "Sistema",
"about": "Acerca de",
"documentation": "Documentación",
"logout": "Cerrar sesión"
} }
} }
+2 -2
View File
@@ -1,5 +1,5 @@
/** /**
* Scheduler tipo cron para KAPPA Hub. * Scheduler tipo cron para Alpha.
* *
* Las tareas se ejecutan solo cuando la app está abierta (web app). * Las tareas se ejecutan solo cuando la app está abierta (web app).
* En RUMBO (Tauri) esto se vuelve un proceso en segundo plano real. * En RUMBO (Tauri) esto se vuelve un proceso en segundo plano real.
@@ -38,7 +38,7 @@ interface ExecutionLog {
message: string message: string
} }
const db = new Dexie('kappa-hub-scheduler') as Dexie & { const db = new Dexie('alpha-scheduler') as Dexie & {
rules: EntityTable<ScheduleRule, 'id'> rules: EntityTable<ScheduleRule, 'id'>
logs: EntityTable<ExecutionLog, 'id'> logs: EntityTable<ExecutionLog, 'id'>
} }
+1 -1
View File
@@ -19,7 +19,7 @@ export const useProjectsStore = defineStore('projects', () => {
loading.value = true loading.value = true
error.value = null error.value = null
try { try {
const data = await kappa.getInitiatives() const data = await kappa.getInitiatives() as KappaInitiative[] | { results?: KappaInitiative[] }
console.log('[KAPPA] initiatives:', data) console.log('[KAPPA] initiatives:', data)
projects.value = Array.isArray(data) ? data : (data.results ?? []) projects.value = Array.isArray(data) ? data : (data.results ?? [])
} catch (e: any) { } catch (e: any) {
+6 -3
View File
@@ -44,9 +44,12 @@ export const useWorkItemsStore = defineStore('workitems', () => {
kappa.getLogbooks(initiativeId), kappa.getLogbooks(initiativeId),
kappa.getPlannings(initiativeId), kappa.getPlannings(initiativeId),
]) ])
userStories.value = Array.isArray(stories) ? stories : (stories.results ?? []) const storiesData = stories as KappaUserStory[] | { results?: KappaUserStory[] }
logbooks.value = Array.isArray(logs) ? logs : (logs.results ?? []) const logsData = logs as KappaLogbookEntry[] | { results?: KappaLogbookEntry[] }
plannings.value = Array.isArray(plans) ? plans : (plans.results ?? []) const plansData = plans as KappaPlanningEntry[] | { results?: KappaPlanningEntry[] }
userStories.value = Array.isArray(storiesData) ? storiesData : (storiesData.results ?? [])
logbooks.value = Array.isArray(logsData) ? logsData : (logsData.results ?? [])
plannings.value = Array.isArray(plansData) ? plansData : (plansData.results ?? [])
} catch (e: any) { } catch (e: any) {
error.value = e.message error.value = e.message
} finally { } finally {
+1 -1
View File
@@ -25,7 +25,7 @@ async function handleLogin() {
<span class="font-bold text-xl">A</span> <span class="font-bold text-xl">A</span>
</div> </div>
<CardTitle class="text-2xl font-bold tracking-tight">Alpha</CardTitle> <CardTitle class="text-2xl font-bold tracking-tight">Alpha</CardTitle>
<CardDescription class="text-xs mt-1">KAPPA Hub</CardDescription> <CardDescription class="text-xs mt-1">Alpha</CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>