refactor(hr): move Custom Roles from Settings into the HR section
CI/CD / CI · API (dotnet build + test) (push) Successful in 42s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 29s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m8s
CI/CD / CI · Admin Web (tsc) (push) Successful in 39s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 50s
CI/CD / Deploy · all services (push) Successful in 2m47s

Custom roles is staff governance, so it belongs with the team — added a "Roles &
permissions" tab to the HR screen (owner-only) rendering the existing
CustomRolesPanel, and removed the Settings → Team → Custom Roles leaf/group.
fa/en/ar label added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-25 09:38:55 +03:30
parent eaf911e12c
commit aede5bfd97
6 changed files with 19 additions and 27 deletions
+2 -1
View File
@@ -438,7 +438,8 @@
"payroll": "الرواتب", "payroll": "الرواتب",
"access": "صلاحيات الفروع", "access": "صلاحيات الفروع",
"credentials": "بيانات الدخول", "credentials": "بيانات الدخول",
"team": "الموظفون" "team": "الموظفون",
"roles": "الأدوار والصلاحيات"
}, },
"myAttendance": "حضوري", "myAttendance": "حضوري",
"clockIn": "تسجيل دخول", "clockIn": "تسجيل دخول",
+2 -1
View File
@@ -457,7 +457,8 @@
"payroll": "Payroll", "payroll": "Payroll",
"access": "Branch access", "access": "Branch access",
"credentials": "Login credentials", "credentials": "Login credentials",
"team": "Team" "team": "Team",
"roles": "Roles & permissions"
}, },
"myAttendance": "My attendance", "myAttendance": "My attendance",
"clockIn": "Clock in", "clockIn": "Clock in",
+2 -1
View File
@@ -457,7 +457,8 @@
"payroll": "حقوق", "payroll": "حقوق",
"access": "دسترسی شعب", "access": "دسترسی شعب",
"credentials": "رمز ورود", "credentials": "رمز ورود",
"team": "کارکنان" "team": "کارکنان",
"roles": "نقش‌ها و دسترسی‌ها"
}, },
"myAttendance": "حضور من", "myAttendance": "حضور من",
"clockIn": "ورود", "clockIn": "ورود",
+10 -3
View File
@@ -14,6 +14,7 @@ import { Badge } from "@/components/ui/badge";
import { BranchAccessPanel } from "@/components/hr/branch-access-panel"; import { BranchAccessPanel } from "@/components/hr/branch-access-panel";
import { EmployeeCredentialsPanel } from "@/components/hr/employee-credentials-panel"; import { EmployeeCredentialsPanel } from "@/components/hr/employee-credentials-panel";
import { AddEmployeeForm } from "@/components/hr/add-employee-form"; import { AddEmployeeForm } from "@/components/hr/add-employee-form";
import { CustomRolesPanel } from "@/components/settings/custom-roles-panel";
import { UserPlus } from "lucide-react"; import { UserPlus } from "lucide-react";
interface Employee { interface Employee {
@@ -50,7 +51,7 @@ interface Salary {
isPaid: boolean; isPaid: boolean;
} }
type Tab = "team" | "attendance" | "leave" | "payroll" | "access" | "credentials"; type Tab = "team" | "attendance" | "leave" | "payroll" | "access" | "credentials" | "roles";
export function HrScreen() { export function HrScreen() {
const t = useTranslations("hr"); const t = useTranslations("hr");
@@ -58,6 +59,7 @@ export function HrScreen() {
const userId = useAuthStore((s) => s.user?.userId); const userId = useAuthStore((s) => s.user?.userId);
const role = useAuthStore((s) => s.user?.role); const role = useAuthStore((s) => s.user?.role);
const canManageAccess = role === "Owner" || role === "Manager"; const canManageAccess = role === "Owner" || role === "Manager";
const canManageRoles = role === "Owner";
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const [tab, setTab] = useState<Tab>("team"); const [tab, setTab] = useState<Tab>("team");
const [addingEmployee, setAddingEmployee] = useState(false); const [addingEmployee, setAddingEmployee] = useState(false);
@@ -126,8 +128,11 @@ export function HrScreen() {
<h2 className="text-xl font-bold">{t("title")}</h2> <h2 className="text-xl font-bold">{t("title")}</h2>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{((["team", "attendance", "leave", "payroll", "access", "credentials"] as Tab[]).filter( {((["team", "attendance", "leave", "payroll", "access", "credentials", "roles"] as Tab[]).filter(
(key) => (key !== "access" && key !== "credentials") || canManageAccess (key) =>
key === "roles"
? canManageRoles
: (key !== "access" && key !== "credentials") || canManageAccess
)).map((key) => ( )).map((key) => (
<Button <Button
key={key} key={key}
@@ -282,6 +287,8 @@ export function HrScreen() {
{tab === "credentials" && canManageAccess && ( {tab === "credentials" && canManageAccess && (
<EmployeeCredentialsPanel cafeId={cafeId} employees={employees} /> <EmployeeCredentialsPanel cafeId={cafeId} employees={employees} />
)} )}
{tab === "roles" && canManageRoles && <CustomRolesPanel cafeId={cafeId} />}
</div> </div>
); );
} }
@@ -14,7 +14,6 @@ import { SettingsTerminalsPanel } from "@/components/settings/settings-terminals
import { SettingsPrinterPanel } from "@/components/settings/settings-printer-panel"; import { SettingsPrinterPanel } from "@/components/settings/settings-printer-panel";
import { SettingsStationsPanel } from "@/components/settings/settings-stations-panel"; import { SettingsStationsPanel } from "@/components/settings/settings-stations-panel";
import { SettingsPrintTestPanel } from "@/components/settings/settings-print-test-panel"; import { SettingsPrintTestPanel } from "@/components/settings/settings-print-test-panel";
import { CustomRolesPanel } from "@/components/settings/custom-roles-panel";
import { import {
DEFAULT_SETTINGS_LEAF, DEFAULT_SETTINGS_LEAF,
groupForLeaf, groupForLeaf,
@@ -30,7 +29,6 @@ const LEAF_PAGE_TITLE: Record<SettingsLeafId, string> = {
"printer-config": "nav.printerSettings", "printer-config": "nav.printerSettings",
"printer-stations": "nav.printerStations", "printer-stations": "nav.printerStations",
"print-test": "nav.printTest", "print-test": "nav.printTest",
"team-custom-roles": "nav.customRoles",
}; };
export function SettingsScreen() { export function SettingsScreen() {
@@ -46,10 +44,7 @@ export function SettingsScreen() {
const toggleGroup = (group: SettingsGroupId) => { const toggleGroup = (group: SettingsGroupId) => {
setExpandedGroup((prev) => (prev === group ? prev : group)); setExpandedGroup((prev) => (prev === group ? prev : group));
const firstChild = const firstChild = group === "shop" ? "shop-general" : "printer-config";
group === "shop" ? "shop-general" :
group === "team" ? "team-custom-roles" :
"printer-config";
if (groupForLeaf(activeLeaf) !== group) { if (groupForLeaf(activeLeaf) !== group) {
selectLeaf(firstChild); selectLeaf(firstChild);
} }
@@ -115,10 +110,6 @@ export function SettingsScreen() {
onOpenPrinterSettings={() => selectLeaf("printer-config")} onOpenPrinterSettings={() => selectLeaf("printer-config")}
/> />
) : null} ) : null}
{activeLeaf === "team-custom-roles" ? (
<CustomRolesPanel cafeId={cafeId} />
) : null}
</div> </div>
</div> </div>
</div> </div>
@@ -1,4 +1,4 @@
export type SettingsGroupId = "shop" | "printer" | "team"; export type SettingsGroupId = "shop" | "printer";
export type SettingsLeafId = export type SettingsLeafId =
| "shop-general" | "shop-general"
@@ -7,8 +7,7 @@ export type SettingsLeafId =
| "shop-discover" | "shop-discover"
| "printer-config" | "printer-config"
| "printer-stations" | "printer-stations"
| "print-test" | "print-test";
| "team-custom-roles";
export type SettingsNavGroup = { export type SettingsNavGroup = {
id: SettingsGroupId; id: SettingsGroupId;
@@ -36,13 +35,6 @@ export const SETTINGS_NAV: SettingsNavGroup[] = [
{ id: "print-test", labelKey: "nav.printTest" }, { id: "print-test", labelKey: "nav.printTest" },
], ],
}, },
{
id: "team",
labelKey: "nav.team",
children: [
{ id: "team-custom-roles", labelKey: "nav.customRoles" },
],
},
]; ];
export const DEFAULT_SETTINGS_LEAF: SettingsLeafId = "shop-general"; export const DEFAULT_SETTINGS_LEAF: SettingsLeafId = "shop-general";
@@ -50,6 +42,5 @@ export const DEFAULT_SETTINGS_LEAF: SettingsLeafId = "shop-general";
export function groupForLeaf(leaf: SettingsLeafId): SettingsGroupId { export function groupForLeaf(leaf: SettingsLeafId): SettingsGroupId {
if (leaf === "printer-config" || leaf === "printer-stations" || leaf === "print-test") if (leaf === "printer-config" || leaf === "printer-stations" || leaf === "print-test")
return "printer"; return "printer";
if (leaf === "team-custom-roles") return "team";
return "shop"; return "shop";
} }