@ff-admin/core (1.3.3)

Published 2026-05-07 14:43:24 +00:00 by jkeffects in FF-Admin/ff-admin-core

Installation

@ff-admin:registry=
npm install @ff-admin/core@1.3.3
"@ff-admin/core": "1.3.3"

About this package

ff-admin-core

Basis-UI-Funktionalität für ff-admin Anwendungen als wiederverwendbares npm-Package.

Package Content

📋 Inhaltsverzeichnis

Übersicht

@ff-admin/core stellt Basis-UI-Komponenten, Layouts, Stores, Router, Enums und Helper für FF-Admin Anwendungen bereit. Das Package sorgt für eine konsistente UI-Struktur und wiederverwendbare Funktionalität in allen Anwendungen.

Was übernimmt das Package?

🖥️ Basis-UI-Inhalte

  • Wiederverwendbare UI-Komponenten (z.B. Layouts, Tabs, Modals, Icons, Progress Bars)
  • Stores für globale State-Verwaltung (Pinia)
  • Router-Konfiguration und Guards
  • Enum-Definitionen für Permissions, Module, Sections etc.
  • Helper-Funktionen für UI und Kommunikation
  • Socket.IO Client-Integration
  • PWA-Unterstützung
  • Konsistente Styles und globale CSS

Das Package stellt die Basis für alle FF-Admin Anwendungen bereit und sorgt für ein einheitliches UI und Verhalten.

Installation

npm install @ff-admin/core

Wichtig: in der viteConfig der Anwendung muss die Dependency Optimization für das package deaktiviert werden.

export default defineConfig({
  plugins: [
    vue(),
    VitePWA({ /* deine config */ }), // falls pwa benötigt
    // ... andere plugins
  ],
  optimizeDeps: {
    exclude: ['@ff-admin/core']
  }
}) 

Peer Dependencies

Das Package benötigt folgende Peer Dependencies:

  • vue >= 3.0.0
  • pinia >= 2.0.0
  • vue-router >= 4.0.0

Verwendung & Erweiterung

Das Package wird typischerweise in den zentralen Dateien der Anwendung (z.B. core-setup.ts, main.ts, router/index.ts) eingebunden und konfiguriert. Die Erweiterung erfolgt über TypeScript-Interfaces, um projektspezifische Funktionalität und Enums zu ergänzen.

Einbindung und Initialisierung

  • Importiere das Package und initialisiere zentrale Services (z.B. HTTP, Socket, Konfigurationswerte).
  • Binde globale Komponenten, Stores und Router ein.
  • Konfiguriere Namespaces, Enums und weitere projektspezifische Typen über Interface-Erweiterungen.

Beispielhafter Ablauf (vereinfacht):

// Importiere das Package und zentrale Services
import "@ff-admin/core";
import { configureSocketNamespace, HTTPManager, NavigationConfigVals, PackageConfigVals, SocketManager } from "@ff-admin/core";

// (Optional) Erweiterung von Typen für projektspezifische Enums und Namespaces
declare module "@ff-admin/core" {
  interface PermissionSectionMap {
    // Eigene Berechtigungs-Section hinzufügen
    mySection: void;
  }
  interface PermissionModuleMap {
    // Eigene Berechtigungs-Module hinzufügen
    myModule: void;
    anotherModule: void;
  }
  interface SettingTopicMap {
    myApp: void;
  }
  interface SettingValueMapping {
    "myApp.apiKey": string;
    "myApp.timeout": number;
    "myApp.baseUrl": string;
  }
  interface ModuleSettingTopicMap {
    myModule: void;
  }
  interface ModuleSettingValueMapping {
    "myModule.setting1": string;
    "myModule.setting2": number;
    "myModule.enabled": boolean;
  }
  interface SocketNamespaceMap {
    myCustomNamespace: "/custom";
    anotherNamespace: "/another";
  }
}

// Konfigurationswerte setzen
PackageConfigVals.serverAddress = "...";
PackageConfigVals.devMode = true;
PackageConfigVals.clientVersion = ""; // Alternativ package JSON auslesen

// Initialisierung und Konfiguration
HTTPManager.init();
SocketManager.init();
configureSocketNamespace({
  myCustomNamespace: "/custom",
  anotherNamespace: "/another",
});

// Angabe der Navigationsstruktur
NavigationConfigVals.defaultActiveNavigation = "configuration"
NavigationConfigVals.topLevel = [/*...*/]
// direktes setzen der Struktur
NavigationConfigVals.navigation = {/*...*/}
// oder einzelne Keys setzen
NavigationConfigVals.setNavigationKey("configuration", {/*...*/})

Werte wie im Backend müssen nur für den SocketNamespace definiert werden. Alle anderen Konfigurationswerte werden über den Server bezogen.

Integration in die App

  • Binde das Package in die Hauptdatei deiner App ein (z.B. in main.ts).
  • Verwende die bereitgestellten Komponenten, Stores, Router und Helper in deiner Anwendung.
  • Nutze die Basisrouten und Guards aus dem Package und ergänze sie bei Bedarf um eigene Routen.

Beispiel (allgemein):

import "./core-setup";
import { createApp } from "vue";
import { createPinia } from "pinia";
import router from "./router";
import App from "./App.vue";

const app = createApp(App);
app.use(createPinia());
app.use(router);
// Weitere globale Properties oder Plugins
PackageConfigVals.router = router;
app.mount("#app");

CSS-Klassen & Theming

Einbindung in der Anwendung

Damit Styling und Tailwind-Utilities korrekt funktionieren, sind drei Schritte notwendig:

1. vite.config.ts — Tailwind-Plugin einbinden

import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [
    tailwindcss(),
    // ... weitere Plugins
  ],
  optimizeDeps: {
    exclude: ["@ff-admin/core"],
  },
});

2. src/main.css — CSS in der richtigen Reihenfolge importieren

/* 1. Tailwind selbst */
@import "tailwindcss";

/* 2. Rohe Theme-Konfiguration des Package, damit der App-Build 
      die Tokens und Variants kennt */
@import "@ff-admin/core/theme.css";

/* 3. Fertig kompilierte Package-Styles (Komponenten, Base-Layer) */
@import "@ff-admin/core/style.css";

/* 4. Scan-Pfad für Package-Templates, damit Tailwind deren
      verwendete Klassen generiert */
@source "../node_modules/@ff-admin/core/dist/**/*.{js,vue}";

3. src/main.ts — CSS-Datei laden

import "./main.css";

Was die drei Dateien leisten

Import Typ Zweck
@ff-admin/core/theme.css Roh (unkompiliert) Gibt dem Tailwind-Compiler der App die Custom-Tokens (--color-primary etc.) und die hover-Variant ohne @media (hover: hover)
tailwindcss Tailwind Generiert alle Utility-Klassen für die App inkl. der Package-Tokens
@ff-admin/core/style.css Kompiliert Fertige Styles der Package-Komponenten (Base-Layer, Component-Klassen)

Theming — CSS-Variablen

Das gesamte Farbschema leitet sich aus einem einzigen Hue-Wert (0–360, HSL-Farbkreis) ab. Der Wert wird über die Admin-Einstellungen gesetzt und per Pinia-Store zur Laufzeit auf document.documentElement angewendet.

Variable Berechnung Verwendung
--hue 0–360 (Standard: 4 = Rot) Einziger konfigurierbarer Wert
--primary hsl(var(--hue) 100% 30%) Hauptfarbe (Buttons, Rahmen, Header)
--primary-hover hsl(var(--hue) 100% 25%) Hover-Zustand von Primary
--primary-subtle hsl(var(--hue) 100% 93%) Heller Hintergrund (aktive Tabs, Hover-Flächen)
--accent hsl(var(--hue) 80% 40%); Akzent
--success #7ac142 (fix) Erfolg
--failed #ff0000 (fix) Fehler

Alle Variablen sind über Tailwind als Farbklassen verfügbar (z. B. bg-primary, text-primary-subtle, border-primary-hover).


Navigation

.nav-tab

Basis-Klasse für einen Tab in einer Tab-Leiste (z. B. Passwort / TOTP). Wird mit .nav-tab-active oder .nav-tab-inactive kombiniert.

<p class="w-1/2 nav-tab" :class="tab === 'pw' ? 'nav-tab-active' : 'nav-tab-inactive'" @click="tab = 'pw'">
  Passwort
</p>
Klasse Beschreibung
.nav-tab Gemeinsame Basis: flex items-center justify-center, Padding, Schriftgröße
.nav-tab-active Aktiver Tab: bg-primary-subtle, Unterstrich in Primary-Farbe
.nav-tab-inactive Inaktiver Tab: Hover bg-primary-subtle

.nav-toplevel-active / .nav-toplevel-inactive

Für Top-Level-Navigationslinks in der Hauptnavigation (Desktop: ausgefüllter Primary-Hintergrund, Mobil: nur Textfarbe).

Für Einträge in der Seitenleiste. .sidebar-link-active fügt einen linken Primary-Balken und subtilen Hintergrund hinzu.

<div class="sidebar-link" :class="isActive ? 'sidebar-link-active' : ''">Eintrag</div>

Karten & Panels

.card

Weißes, abgerundetes Panel mit horizontalen Trennlinien (divide-y-2 divide-gray-300). Eignet sich für mehrteilige Bereiche.

<div class="card">
  <div class="card-header"></div>
  <div class="p-4">Inhalt</div>
</div>

.card-plain

Wie .card, aber ohne Trennlinien. Für schlichte weiße Panels.

.card-header

Kopfzeile innerhalb einer .card: horizontale Flex-Zeile mit justify-between, Innenabstand.


Listen-Einträge

Alle Listeneinträge (Benutzer, Rollen, Web-API-Keys, Backups, Sitzungen …) folgen diesem Schema:

<div class="list-card">
  <div class="list-card-header">
    <span>Titel</span>
    <span>Aktion</span>
  </div>
  <div class="list-card-body">
    <div class="list-card-row">
      <span class="list-card-row-label">Label</span>
      <span class="list-card-row-value">Wert</span>
    </div>
  </div>
</div>
Klasse Beschreibung
.list-card Äußerer Rahmen mit Primary-Border, abgerundet
.list-card-header Primary-Hintergrund, weißer Text, justify-between
.list-card-body Innenbereich mit Padding und vertikalem Gap
.list-card-row Horizontale Zeile für Label + Wert
.list-card-row-label Feste Mindestbreite (min-w-16) für linksbündige Labels
.list-card-row-value Wächst flexibel, schneidet zu langen Text ab

Modals

Alle Modals verwenden eine einheitliche Struktur:

<div class="modal-wrapper">
  <div class="modal-title">
    <p>Modal-Titel</p>
  </div>

  <!-- Formularfelder -->

  <div class="modal-footer">
    <div class="modal-footer-inner">
      <button>Abbrechen</button>
      <div class="modal-submit-row">
        <button primary>Bestätigen</button>
      </div>
    </div>
  </div>
</div>
Klasse Beschreibung
.modal-wrapper Max-Breite md:max-w-md, volle Breite
.modal-title Zentrierte Flex-Spalte; > p bekommt text-xl font-medium
.modal-footer Rechtsbündige Fußzeile
.modal-footer-inner Horizontale Zeile mit Gap und vertikalem Padding
.modal-submit-row Flex-Zeile für mehrstufige Submit-Aktionen (z. B. Bestätigung + Spinner)

Weitere Utility-Klassen

.badge

Kleines Tag/Chip-Pill für Labels, Rollen, Kanäle o. Ä.

<span class="badge">Admin</span>

Stil: px-2 py-0.5 bg-gray-200 border border-gray-400 rounded-full text-xs

.menu-item

Eintrag in einem Kontext- oder Dropdown-Menü. Hover verwendet bg-primary-subtle.

<div class="menu-item" @click="copy">
  <CopyIcon />
  <span>Kopieren</span>
</div>

.pagination-btn

Einzelne Zelle in einer Pagination-Leiste. first: und last: runden die Enden ab.

<ul class="flex">
  <li class="pagination-btn">«</li>
  <li class="pagination-btn">1</li>
  <li class="pagination-btn">»</li>
</ul>

Öffentliche Seiten (Login, Setup, Reset, Invite)

Für vollseitige zentrierte Seiten ohne Sidebar:

<div class="public-page">
  <div class="public-page-inner">
    <div class="public-page-header">
      <img src="…" alt="Logo" class="h-20 w-auto" />
      <h1 class="public-page-title">Seitentitel</h1>
    </div>

    <!-- Formular oder Inhalt -->
  </div>
</div>
Klasse Beschreibung
.public-page grow flex items-center justify-center, responsives Padding
.public-page-inner max-w-md w-full space-y-8
.public-page-header Flex-Spalte, zentriert, gap-4
.public-page-title text-4xl font-extrabold text-gray-900 text-center

Buttons

Buttons bekommen ihre Variante über HTML-Attribute (kein separates CSS von außen nötig):

<button primary>Primär-Aktion</button>
<button primary-outline>Sekundär-Aktion</button>
<button disabled>Deaktiviert</button>
Attribut Stil
primary Ausgefüllter Primary-Hintergrund, weißer Text, Hover dunkler
primary-outline Primary-Rahmen, transparenter Hintergrund; Hover füllt sich mit Primary
disabled / :disabled opacity-75, kein Klick möglich

Lizenz

AGPL-3.0-only

Author

JK Effects

Repository

https://code.jk-effects.cloud/FF-Admin/ff-admin-core.git

Dependencies

Dependencies

ID Version
@headlessui/vue ^1.7.23
@heroicons/vue ^2.2.0
@simplewebauthn/browser ^13.3.0
@tailwindcss/vite ^4.2.4
@vuepic/vue-datepicker ^12.1.0
@vueuse/core ^14.3.0
axios ^1.16.0
event-source-polyfill ^1.0.31
jwt-decode ^4.0.0
lodash.clonedeep ^4.5.0
lodash.difference ^4.5.0
lodash.differencewith ^4.5.0
lodash.isequal ^4.5.0
ms ^2.1.3
qrcode ^1.5.4
qs ^6.15.1
socket.io-client ^4.8.3
ua-parser-js ^2.0.9
uuid ^14.0.0
vue-qrcode-reader ^5.7.3

Development dependencies

ID Version
@rushstack/eslint-patch ^1.16.1
@tailwindcss/postcss ^4.2.4
@tsconfig/node20 ^20.1.9
@types/eslint ~9.6.1
@types/event-source-polyfill ^1.0.5
@types/lodash.clonedeep ^4.5.9
@types/lodash.difference ^4.5.9
@types/lodash.differencewith ^4.5.9
@types/lodash.isequal ^4.5.8
@types/ms ^2.1.0
@types/node ^25.6.0
@types/nprogress ^0.2.3
@types/qrcode ^1.5.6
@types/qs ^6.15.0
@types/uuid ^11.0.0
@vitejs/plugin-vue ^6.0.6
@vue/eslint-config-typescript ^14.7.0
@vue/tsconfig ^0.9.1
eslint ^10.3.0
eslint-plugin-vue ^10.9.1
npm-run-all2 ^8.0.4
tailwindcss ^4.2.4
typescript ^6.0.3
vite ^7.3.2
vite-plugin-dts ^4.5.4
vite-plugin-pwa ^1.3.0
vue-tsc ^3.2.8

Peer dependencies

ID Version
nprogress >=0.2.0
pinia >=3.0.4
quill ^2.0.3
quill-cursors ^4.0.4
vue >=3.5.27
vue-router >=5.0.2

Keywords

Feuerwehr ff-admin
Details
npm
2026-05-07 14:43:24 +00:00
13
JK Effects
AGPL-3.0-only
806 KiB
Assets (1)
core-1.3.3.tgz 806 KiB
Versions (23) View all
1.4.1 2026-05-18
1.4.0 2026-05-17
1.3.3 2026-05-07
1.3.2 2026-05-06
1.3.1 2026-05-05