81 lines
2.4 KiB
TypeScript
81 lines
2.4 KiB
TypeScript
import { usePage } from '@inertiajs/vue3';
|
|
import { computed } from 'vue';
|
|
import type { SharedProps, SlotPayload } from '@/types';
|
|
|
|
/**
|
|
* Translate a string using the JSON catalog shared by the server.
|
|
*
|
|
* Mirrors Laravel's __() helper: the English string is the key, and :placeholder
|
|
* tokens are replaced from the supplied arguments.
|
|
*/
|
|
export function useTranslations() {
|
|
const page = usePage<SharedProps>();
|
|
|
|
const __ = (key: string, replacements: Record<string, string | number> = {}): string => {
|
|
// `||` rather than `??` to mirror Laravel's `$line ?: $key`. Plugins ship
|
|
// English catalogs whose values are empty strings, and those must fall
|
|
// back to the key exactly as they do server side.
|
|
let line = page.props.translations?.[key] || key;
|
|
|
|
for (const [token, value] of Object.entries(replacements)) {
|
|
line = line.replace(`:${token}`, String(value));
|
|
}
|
|
|
|
return line;
|
|
};
|
|
|
|
return { __ };
|
|
}
|
|
|
|
/**
|
|
* Permission and role checks, replacing the @permission / @role Blade directives.
|
|
*/
|
|
export function usePermissions() {
|
|
const page = usePage<SharedProps>();
|
|
|
|
const permissions = computed(() => page.props.auth.permissions ?? []);
|
|
|
|
/** True when the user has every one of the given permissions. */
|
|
const can = (...required: string[]): boolean =>
|
|
required.every((permission) => permissions.value.includes(permission));
|
|
|
|
/** True when the user has at least one of the given permissions. */
|
|
const canAny = (...required: string[]): boolean =>
|
|
required.some((permission) => permissions.value.includes(permission));
|
|
|
|
return { permissions, can, canAny };
|
|
}
|
|
|
|
/**
|
|
* The authenticated user, or null for guest pages.
|
|
*/
|
|
export function useAuth() {
|
|
const page = usePage<SharedProps>();
|
|
|
|
return {
|
|
user: computed(() => page.props.auth.user),
|
|
impersonating: computed(() => page.props.auth.impersonating),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* A shared application setting.
|
|
*/
|
|
export function useSettings() {
|
|
const page = usePage<SharedProps>();
|
|
|
|
const setting = <T = unknown>(key: string, fallback: T | null = null): T | null =>
|
|
(page.props.settings?.[key] as T) ?? fallback;
|
|
|
|
return { setting };
|
|
}
|
|
|
|
/**
|
|
* Components registered by plugins for a named slot position.
|
|
*/
|
|
export function useSlot(name: string) {
|
|
const page = usePage<SharedProps>();
|
|
|
|
return computed<SlotPayload[]>(() => page.props.vanguard?.slots?.[name] ?? []);
|
|
}
|