mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-21 21:33:02 +01:00
* feat: implement example of data table * feat: load item data into table * chore: begin switching dialogs * feat: implement old dialog for controlling headers and page size * feat: get table into relatively usable state * feat: enhance dropdown actions for multi-selection and CSV download * feat: enhance table cell and dropdown button styles for better usability * feat: json download for table * feat: add expanded row component for item details in data table * chore: add translation support * feat: restore table on home page * fix: oops need ids * feat: move card view to use tanstack to allow for pagination * feat: switch the items search to use ItemViewSelectable * fix: update pagination handling and improve button click logic * feat: improve selectable table * feat: add indeterminate to checkbox * feat: overhaul maintenance dialog to use new system and add maintenance options to table * feat: add label ids and location id to item patch api * feat: change location and labels in table view * feat: add quick actions preference and enable toggle in table settings * fix: lint * fix: remove sized 1 pages * fix: attempt to fix type error * fix: various issues * fix: remove * fix: refactor item fetching logic to use useAsyncData for improved reactivity and improve use confirm * fix: sort backend issues * fix: enhance CSV export functionality by escaping fields to prevent formula injection * fix: put aria sort on th not button * chore: update api types
47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
import type { Updater } from "@tanstack/vue-table";
|
|
import { type ClassValue, clsx } from "clsx";
|
|
import { twMerge } from "tailwind-merge";
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
export function valueUpdater<T extends Updater<any>>(updaterOrValue: T, ref: Ref) {
|
|
ref.value = typeof updaterOrValue === "function" ? updaterOrValue(ref.value) : updaterOrValue;
|
|
}
|
|
|
|
/**
|
|
* Returns either '#000' or '#fff' depending on which has better contrast with the given background color.
|
|
* Accepts hex (#RRGGBB or #RGB) or rgb(a) strings.
|
|
*/
|
|
export function getContrastTextColor(bgColor: string): string {
|
|
let r = 0;
|
|
let g = 0;
|
|
let b = 0;
|
|
if (bgColor.startsWith("#")) {
|
|
let hex = bgColor.slice(1);
|
|
if (hex.length === 3) {
|
|
hex = hex
|
|
.split("")
|
|
.map(x => x + x)
|
|
.join("");
|
|
}
|
|
r = parseInt(hex.slice(0, 2), 16);
|
|
g = parseInt(hex.slice(2, 4), 16);
|
|
b = parseInt(hex.slice(4, 6), 16);
|
|
} else if (bgColor.startsWith("rgb")) {
|
|
const match = bgColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/) as [string, string, string, string];
|
|
if (match) {
|
|
r = parseInt(match[1]);
|
|
g = parseInt(match[2]);
|
|
b = parseInt(match[3]);
|
|
}
|
|
}
|
|
// Calculate luminance
|
|
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
return luminance > 0.5 ? "#000" : "#fff";
|
|
}
|
|
|
|
export const camelToSnakeCase = (str: string) => str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
|