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
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:
@@ -438,7 +438,8 @@
|
|||||||
"payroll": "الرواتب",
|
"payroll": "الرواتب",
|
||||||
"access": "صلاحيات الفروع",
|
"access": "صلاحيات الفروع",
|
||||||
"credentials": "بيانات الدخول",
|
"credentials": "بيانات الدخول",
|
||||||
"team": "الموظفون"
|
"team": "الموظفون",
|
||||||
|
"roles": "الأدوار والصلاحيات"
|
||||||
},
|
},
|
||||||
"myAttendance": "حضوري",
|
"myAttendance": "حضوري",
|
||||||
"clockIn": "تسجيل دخول",
|
"clockIn": "تسجيل دخول",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -457,7 +457,8 @@
|
|||||||
"payroll": "حقوق",
|
"payroll": "حقوق",
|
||||||
"access": "دسترسی شعب",
|
"access": "دسترسی شعب",
|
||||||
"credentials": "رمز ورود",
|
"credentials": "رمز ورود",
|
||||||
"team": "کارکنان"
|
"team": "کارکنان",
|
||||||
|
"roles": "نقشها و دسترسیها"
|
||||||
},
|
},
|
||||||
"myAttendance": "حضور من",
|
"myAttendance": "حضور من",
|
||||||
"clockIn": "ورود",
|
"clockIn": "ورود",
|
||||||
|
|||||||
@@ -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";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user