updated services web user selection
This commit is contained in:
parent
8573c8021b
commit
b73417a625
|
|
@ -210,7 +210,7 @@ class LoginHandler:
|
||||||
|
|
||||||
user_dict = found_user.get_dict()
|
user_dict = found_user.get_dict()
|
||||||
person_dict = found_user.person.get_dict()
|
person_dict = found_user.person.get_dict()
|
||||||
|
|
||||||
for living_space in living_spaces:
|
for living_space in living_spaces:
|
||||||
build_part = BuildParts.query.filter(BuildParts.id == living_space.build_parts_id).first()
|
build_part = BuildParts.query.filter(BuildParts.id == living_space.build_parts_id).first()
|
||||||
if not build_part:
|
if not build_part:
|
||||||
|
|
@ -344,7 +344,12 @@ class LoginHandler:
|
||||||
# TODO: erase this bypass later
|
# TODO: erase this bypass later
|
||||||
filter_endpoints_and_events = db_session.query(EndpointRestriction.operation_uu_id, Events.function_code
|
filter_endpoints_and_events = db_session.query(EndpointRestriction.operation_uu_id, Events.function_code
|
||||||
).join(EndpointRestriction, EndpointRestriction.id == Events.endpoint_id).filter().all()
|
).join(EndpointRestriction, EndpointRestriction.id == Events.endpoint_id).filter().all()
|
||||||
|
|
||||||
|
# Get reachable applications
|
||||||
|
reachable_app_codes = Application2Employee.get_application_codes(employee_id=int(result_with_keys_dict['Employees.id']), db=db_session)
|
||||||
|
# Get reachable events
|
||||||
reachable_event_codes = {endpoint_name: function_code for endpoint_name, function_code in filter_endpoints_and_events}
|
reachable_event_codes = {endpoint_name: function_code for endpoint_name, function_code in filter_endpoints_and_events}
|
||||||
|
|
||||||
add_company = {
|
add_company = {
|
||||||
"uu_id": str(result_with_keys_dict["Employees.uu_id"]),
|
"uu_id": str(result_with_keys_dict["Employees.uu_id"]),
|
||||||
"public_name": result_with_keys_dict["Companies.public_name"],
|
"public_name": result_with_keys_dict["Companies.public_name"],
|
||||||
|
|
@ -356,7 +361,7 @@ class LoginHandler:
|
||||||
redis_handler = RedisHandlers()
|
redis_handler = RedisHandlers()
|
||||||
user_uu_id = Users.query.filter(Users.person_id == result_with_keys_dict['People.id']).first().uu_id
|
user_uu_id = Users.query.filter(Users.person_id == result_with_keys_dict['People.id']).first().uu_id
|
||||||
redis_result = redis_handler.update_token_at_redis(token=access_token, add_payload=add_company, user_uuid=user_uu_id)
|
redis_result = redis_handler.update_token_at_redis(token=access_token, add_payload=add_company, user_uuid=user_uu_id)
|
||||||
return {"selected_uu_id": data.uuid}
|
return {"selected_uu_id": data.uuid, "reachable_app_codes": reachable_app_codes}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def handle_occupant_selection(cls, access_token: str, data: Any, token_dict: TokenDictType):
|
def handle_occupant_selection(cls, access_token: str, data: Any, token_dict: TokenDictType):
|
||||||
|
|
@ -391,7 +396,9 @@ class LoginHandler:
|
||||||
reachable_event_codes = {endpoint_name: function_code for endpoint_name, function_code in filter_endpoints_and_events}
|
reachable_event_codes = {endpoint_name: function_code for endpoint_name, function_code in filter_endpoints_and_events}
|
||||||
|
|
||||||
# Get reachable applications
|
# Get reachable applications
|
||||||
|
print('selected_build_living_space_first', selected_build_living_space_first.id)
|
||||||
reachable_app_codes = Application2Occupant.get_application_codes(build_living_space_id=selected_build_living_space_first.id, db=db)
|
reachable_app_codes = Application2Occupant.get_application_codes(build_living_space_id=selected_build_living_space_first.id, db=db)
|
||||||
|
print('reachable_app_codes', reachable_app_codes)
|
||||||
|
|
||||||
build_part = BuildParts.query.filter(BuildParts.id == result_with_keys_dict['BuildParts.id']).first()
|
build_part = BuildParts.query.filter(BuildParts.id == result_with_keys_dict['BuildParts.id']).first()
|
||||||
if not build_part:
|
if not build_part:
|
||||||
|
|
@ -410,7 +417,7 @@ class LoginHandler:
|
||||||
|
|
||||||
user_uu_id = Users.query.filter(Users.person_id == result_with_keys_dict['People.id']).first().uu_id
|
user_uu_id = Users.query.filter(Users.person_id == result_with_keys_dict['People.id']).first().uu_id
|
||||||
redis_handler.update_token_at_redis(token=access_token, add_payload=add_build_living_space, user_uuid=user_uu_id)
|
redis_handler.update_token_at_redis(token=access_token, add_payload=add_build_living_space, user_uuid=user_uu_id)
|
||||||
return {"selected_uu_id": data.uuid}
|
return {"selected_uu_id": data.uuid, "reachable_app_codes": reachable_app_codes}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def authentication_select_company_or_occupant_type(cls, request: Any, data: Any):
|
def authentication_select_company_or_occupant_type(cls, request: Any, data: Any):
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,14 @@ class PageHandlers:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def retrieve_valid_sites_via_token(cls, access_token: str) -> list:
|
def retrieve_valid_sites_via_token(cls, access_token: str) -> list:
|
||||||
"""
|
""" Retrieve valid pages via token. {"access_token": "string"} | Results: list(sites) """
|
||||||
Retrieve valid pages via token. {"access_token": "string"} | Results: list(sites)
|
|
||||||
"""
|
|
||||||
if result := RedisHandlers.get_object_from_redis(access_token=access_token):
|
if result := RedisHandlers.get_object_from_redis(access_token=access_token):
|
||||||
if result.is_employee:
|
if result.is_employee and result.selected_company:
|
||||||
if result.selected_company and result.selected_company.reachable_app_codes:
|
employee_uuid = result.selected_company.get("employee_uu_id", "")
|
||||||
return result.selected_company.reachable_app_codes.keys()
|
if reachable_app_codes_dict := result.reachable_app_codes:
|
||||||
elif result.is_occupant:
|
return reachable_app_codes_dict.get(employee_uuid, {}).keys()
|
||||||
if result.selected_occupant and result.selected_occupant.reachable_app_codes:
|
elif result.is_occupant and result.selected_occupant:
|
||||||
return result.selected_occupant.reachable_app_codes.keys()
|
living_space_uu_id = result.selected_occupant.get("build_living_space_uu_id", "")
|
||||||
|
if reachable_app_codes_dict := result.reachable_app_codes:
|
||||||
|
return reachable_app_codes_dict.get(living_space_uu_id, {}).keys()
|
||||||
raise ValueError("EYS_0013")
|
raise ValueError("EYS_0013")
|
||||||
|
|
|
||||||
|
|
@ -211,19 +211,11 @@ class Service2Application(CrudCollection):
|
||||||
__tablename__ = "services2applications"
|
__tablename__ = "services2applications"
|
||||||
__exclude__fields__ = []
|
__exclude__fields__ = []
|
||||||
|
|
||||||
application_id: Mapped[int] = mapped_column(
|
application_id: Mapped[int] = mapped_column(ForeignKey("applications.id"), nullable=False)
|
||||||
ForeignKey("applications.id"), nullable=False
|
application_uu_id: Mapped[str] = mapped_column(String, nullable=False, comment="Application UUID")
|
||||||
)
|
|
||||||
application_uu_id: Mapped[str] = mapped_column(
|
|
||||||
String, nullable=False, comment="Application UUID"
|
|
||||||
)
|
|
||||||
service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False)
|
service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False)
|
||||||
service_uu_id: Mapped[str] = mapped_column(
|
service_uu_id: Mapped[str] = mapped_column(String, nullable=False, comment="Service UUID")
|
||||||
String, nullable=False, comment="Service UUID"
|
application_code: Mapped[str] = mapped_column(String, nullable=False, comment="Application Code")
|
||||||
)
|
|
||||||
application_code: Mapped[str] = mapped_column(
|
|
||||||
String, nullable=False, comment="Application Code"
|
|
||||||
)
|
|
||||||
site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL")
|
site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL")
|
||||||
|
|
||||||
__table_args__ = {"comment": "Service2Applications Information"}
|
__table_args__ = {"comment": "Service2Applications Information"}
|
||||||
|
|
@ -237,13 +229,9 @@ class Event2OccupantExtra(CrudCollection):
|
||||||
build_living_space_id: Mapped[int] = mapped_column(
|
build_living_space_id: Mapped[int] = mapped_column(
|
||||||
ForeignKey("build_living_space.id"), nullable=False
|
ForeignKey("build_living_space.id"), nullable=False
|
||||||
)
|
)
|
||||||
build_living_space_uu_id: Mapped[str] = mapped_column(
|
build_living_space_uu_id: Mapped[str] = mapped_column(String, nullable=False, comment="Build Living Space UUID")
|
||||||
String, nullable=False, comment="Build Living Space UUID"
|
|
||||||
)
|
|
||||||
event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), nullable=False)
|
event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), nullable=False)
|
||||||
event_uu_id: Mapped[str] = mapped_column(
|
event_uu_id: Mapped[str] = mapped_column(String, nullable=False, comment="Event UUID")
|
||||||
String, nullable=False, comment="Event UUID"
|
|
||||||
)
|
|
||||||
|
|
||||||
__table_args__ = (
|
__table_args__ = (
|
||||||
Index(
|
Index(
|
||||||
|
|
@ -265,14 +253,10 @@ class Event2EmployeeExtra(CrudCollection):
|
||||||
__exclude__fields__ = []
|
__exclude__fields__ = []
|
||||||
|
|
||||||
employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False)
|
employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False)
|
||||||
employee_uu_id: Mapped[str] = mapped_column(
|
employee_uu_id: Mapped[str] = mapped_column(String, nullable=False, comment="Employee UUID")
|
||||||
String, nullable=False, comment="Employee UUID"
|
|
||||||
)
|
|
||||||
|
|
||||||
event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), nullable=False)
|
event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), nullable=False)
|
||||||
event_uu_id: Mapped[str] = mapped_column(
|
event_uu_id: Mapped[str] = mapped_column(String, nullable=False, comment="Event UUID")
|
||||||
String, nullable=False, comment="Event UUID"
|
|
||||||
)
|
|
||||||
|
|
||||||
__table_args__ = (
|
__table_args__ = (
|
||||||
Index(
|
Index(
|
||||||
|
|
@ -447,12 +431,8 @@ class Application2Occupant(CrudCollection):
|
||||||
__tablename__ = "application2occupant"
|
__tablename__ = "application2occupant"
|
||||||
__exclude__fields__ = []
|
__exclude__fields__ = []
|
||||||
|
|
||||||
build_living_space_id: Mapped[int] = mapped_column(
|
build_living_space_id: Mapped[int] = mapped_column(ForeignKey("build_living_space.id"), nullable=False)
|
||||||
ForeignKey("build_living_space.id"), nullable=False
|
build_living_space_uu_id = mapped_column(String, nullable=False, comment="Build Living Space UUID")
|
||||||
)
|
|
||||||
build_living_space_uu_id = mapped_column(
|
|
||||||
String, nullable=False, comment="Build Living Space UUID"
|
|
||||||
)
|
|
||||||
service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False)
|
service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False)
|
||||||
service_uu_id = mapped_column(String, nullable=False, comment="Service UUID")
|
service_uu_id = mapped_column(String, nullable=False, comment="Service UUID")
|
||||||
|
|
||||||
|
|
@ -462,6 +442,7 @@ class Application2Occupant(CrudCollection):
|
||||||
Service2Application.set_session(db)
|
Service2Application.set_session(db)
|
||||||
Applications.set_session(db)
|
Applications.set_session(db)
|
||||||
Application2OccupantExtra.set_session(db)
|
Application2OccupantExtra.set_session(db)
|
||||||
|
|
||||||
occupant_services = cls.query.filter(cls.build_living_space_id == build_living_space_id).all()
|
occupant_services = cls.query.filter(cls.build_living_space_id == build_living_space_id).all()
|
||||||
service_ids = [service.service_id for service in occupant_services]
|
service_ids = [service.service_id for service in occupant_services]
|
||||||
active_applications = Service2Application.query.filter(Service2Application.service_id.in_(service_ids)).all()
|
active_applications = Service2Application.query.filter(Service2Application.service_id.in_(service_ids)).all()
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { NextResponse } from "next/server";
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
try {
|
try {
|
||||||
const menu = await getMenuFromRedis();
|
const menu = await getMenuFromRedis();
|
||||||
|
console.log("menu", menu);
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 200,
|
status: 200,
|
||||||
data: menu,
|
data: menu,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { loginViaAccessKeys, initFirstSelection } from "@/fetchers/custom/login/login";
|
import {
|
||||||
|
loginViaAccessKeys,
|
||||||
|
initFirstSelection,
|
||||||
|
} from "@/fetchers/custom/login/login";
|
||||||
import { loginSchemaEmail } from "@/pages/single/auth/login/schemas";
|
import { loginSchemaEmail } from "@/pages/single/auth/login/schemas";
|
||||||
|
|
||||||
export async function POST(req: Request): Promise<NextResponse> {
|
export async function POST(req: Request): Promise<NextResponse> {
|
||||||
|
|
@ -20,7 +23,11 @@ export async function POST(req: Request): Promise<NextResponse> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const userLogin = await loginViaAccessKeys(dataValidated);
|
const userLogin = await loginViaAccessKeys(dataValidated);
|
||||||
await initFirstSelection(userLogin.data?.firstSelection, userLogin.data?.userType);
|
console.log("userLogin", userLogin);
|
||||||
|
await initFirstSelection(
|
||||||
|
userLogin.data?.firstSelection,
|
||||||
|
userLogin.data?.userType
|
||||||
|
);
|
||||||
if (userLogin.status === 200 || userLogin.status === 202) {
|
if (userLogin.status === 200 || userLogin.status === 202) {
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 200,
|
status: 200,
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,10 @@ interface ClientSelectionSectionProps {
|
||||||
selectionData: any;
|
selectionData: any;
|
||||||
refreshSelection: () => Promise<void>;
|
refreshSelection: () => Promise<void>;
|
||||||
updateSelection: (newSelection: any) => Promise<boolean>;
|
updateSelection: (newSelection: any) => Promise<boolean>;
|
||||||
|
refreshMenu: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ClientSelectionSection: FC<ClientSelectionSectionProps> = ({ selectionData, refreshSelection, updateSelection }) => {
|
const ClientSelectionSection: FC<ClientSelectionSectionProps> = ({ selectionData, refreshSelection, updateSelection, refreshMenu }) => {
|
||||||
const [expandedBuilds, setExpandedBuilds] = useState<{ [key: string]: boolean }>({});
|
const [expandedBuilds, setExpandedBuilds] = useState<{ [key: string]: boolean }>({});
|
||||||
|
|
||||||
if (!selectionData || !selectionData.selectionList) { return null }
|
if (!selectionData || !selectionData.selectionList) { return null }
|
||||||
|
|
@ -21,7 +22,7 @@ const ClientSelectionSection: FC<ClientSelectionSectionProps> = ({ selectionData
|
||||||
selectionData.selectionList.map((client: any, index: number) => {
|
selectionData.selectionList.map((client: any, index: number) => {
|
||||||
return (
|
return (
|
||||||
<div key={client.uu_id || client.id || `client-${index}`}>
|
<div key={client.uu_id || client.id || `client-${index}`}>
|
||||||
{client && renderOneClientSelection({ item: client, selectedItem: selectionData.activeSelection, updateSelection, refreshSelection })}
|
{client && renderOneClientSelection({ item: client, selectedItem: selectionData.activeSelection, updateSelection, refreshSelection, refreshMenu })}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|
@ -63,7 +64,7 @@ const ClientSelectionSection: FC<ClientSelectionSectionProps> = ({ selectionData
|
||||||
{buildData.occupants && Array.isArray(buildData.occupants) ? (
|
{buildData.occupants && Array.isArray(buildData.occupants) ? (
|
||||||
buildData.occupants.map((client: any, index: number) => (
|
buildData.occupants.map((client: any, index: number) => (
|
||||||
<div key={client.occupant_uu_id || client.part_uu_id || `occupant-${index}`}>
|
<div key={client.occupant_uu_id || client.part_uu_id || `occupant-${index}`}>
|
||||||
{client && renderOneClientSelection({ item: client, selectedItem: selectionData.activeSelection, updateSelection, refreshSelection })}
|
{client && renderOneClientSelection({ item: client, selectedItem: selectionData.activeSelection, updateSelection, refreshSelection, refreshMenu })}
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
) : (<div>No occupants found</div>)}
|
) : (<div>No occupants found</div>)}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import ClientSelectionSection from "./clientSelectionSection";
|
||||||
import MenuItemsSection from "./menuItemsSection";
|
import MenuItemsSection from "./menuItemsSection";
|
||||||
import MenuLoadingState from "./menuLoadingState";
|
import MenuLoadingState from "./menuLoadingState";
|
||||||
import MenuErrorState from "./menuErrorState";
|
import MenuErrorState from "./menuErrorState";
|
||||||
import MenuEmptyState from "./menuEmptyState";
|
|
||||||
import LoadingContent from "@/components/mutual/loader/component";
|
import LoadingContent from "@/components/mutual/loader/component";
|
||||||
|
|
||||||
const MenuComponent: FC<MenuProps> = ({
|
const MenuComponent: FC<MenuProps> = ({
|
||||||
|
|
@ -20,8 +20,7 @@ const MenuComponent: FC<MenuProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
if (menuLoading) { return <MenuLoadingState /> }
|
if (menuLoading) { return <MenuLoadingState /> }
|
||||||
if (menuError) { return <MenuErrorState error={menuError} />; }
|
if (menuError) { return <MenuErrorState error={menuError} />; }
|
||||||
if (availableApplications.length === 0) { return <MenuEmptyState />; }
|
|
||||||
|
|
||||||
const lang = onlineData?.lang as LanguageTypes || 'en';
|
const lang = onlineData?.lang as LanguageTypes || 'en';
|
||||||
return (
|
return (
|
||||||
<div className="fixed top-24 p-5 left-0 right-0 w-80 border-emerald-150 border-r-2 overflow-y-auto h-[calc(100vh-6rem)]">
|
<div className="fixed top-24 p-5 left-0 right-0 w-80 border-emerald-150 border-r-2 overflow-y-auto h-[calc(100vh-6rem)]">
|
||||||
|
|
@ -32,7 +31,7 @@ const MenuComponent: FC<MenuProps> = ({
|
||||||
</Suspense>
|
</Suspense>
|
||||||
{/* Client Selection Section */}
|
{/* Client Selection Section */}
|
||||||
<Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}>
|
<Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}>
|
||||||
<ClientSelectionSection selectionData={selectionData} refreshSelection={refreshSelection} updateSelection={updateSelection} />
|
<ClientSelectionSection selectionData={selectionData} refreshSelection={refreshSelection} updateSelection={updateSelection} refreshMenu={refreshMenu} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
{/* Menu Items Section */}
|
{/* Menu Items Section */}
|
||||||
<Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}>
|
<Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import {
|
||||||
MenuStructure,
|
MenuStructure,
|
||||||
MenuItemsSectionProps,
|
MenuItemsSectionProps,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
import MenuEmptyState from "./menuEmptyState";
|
||||||
|
|
||||||
const menuStaticTranslation = {
|
const menuStaticTranslation = {
|
||||||
tr: { menu: "Menü" },
|
tr: { menu: "Menü" },
|
||||||
|
|
@ -26,6 +26,7 @@ const MenuItemsSection: FC<MenuItemsSectionProps> = ({ availableApplications, ac
|
||||||
const [activeSecondLayer, setActiveSecondLayer] = useState<string | null>(null);
|
const [activeSecondLayer, setActiveSecondLayer] = useState<string | null>(null);
|
||||||
const [activeThirdLayer, setActiveThirdLayer] = useState<string | null>(null);
|
const [activeThirdLayer, setActiveThirdLayer] = useState<string | null>(null);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newMenuStructure: MenuStructure = {};
|
const newMenuStructure: MenuStructure = {};
|
||||||
const menuTranslationWLang = menuTranslation[lang as keyof typeof menuTranslation];
|
const menuTranslationWLang = menuTranslation[lang as keyof typeof menuTranslation];
|
||||||
|
|
@ -82,6 +83,8 @@ const MenuItemsSection: FC<MenuItemsSectionProps> = ({ availableApplications, ac
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderFirstLayerItems = () => {
|
const renderFirstLayerItems = () => {
|
||||||
|
|
||||||
|
|
||||||
return Object.entries(menuStructure).map(([firstLayerKey, secondLayerItems]) => {
|
return Object.entries(menuStructure).map(([firstLayerKey, secondLayerItems]) => {
|
||||||
const isActive = activeFirstLayer === firstLayerKey;
|
const isActive = activeFirstLayer === firstLayerKey;
|
||||||
const isExpanded = expandedFirstLayer === firstLayerKey;
|
const isExpanded = expandedFirstLayer === firstLayerKey;
|
||||||
|
|
@ -92,13 +95,35 @@ const MenuItemsSection: FC<MenuItemsSectionProps> = ({ availableApplications, ac
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={`${firstLayerKey}-item`} className="mb-2">
|
<div key={`${firstLayerKey}-item`} className="mb-2">
|
||||||
<FirstLayerDropdown isActive={isActive} isExpanded={isExpanded} innerText={displayText} onClick={() => handleFirstLayerClick(firstLayerKey)} />
|
{<FirstLayerDropdown isActive={isActive} isExpanded={isExpanded} innerText={displayText} onClick={() => handleFirstLayerClick(firstLayerKey)} />}
|
||||||
{isExpanded && <div className="mt-1">{renderSecondLayerItems(firstLayerKey, secondLayerItems)}</div>}
|
{isExpanded && <div className="mt-1">{renderSecondLayerItems(firstLayerKey, secondLayerItems)}</div>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return <div className="mt-1"><h3 className="text-sm font-semibold mb-1">{menuStaticTranslation[lang as keyof typeof menuStaticTranslation].menu}</h3>{renderFirstLayerItems()}</div>;
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="mt-1 flex justify-center"><h3 className="text-sm font-semibold mb-1">{menuStaticTranslation[lang as keyof typeof menuStaticTranslation].menu}</h3></div>
|
||||||
|
<br />
|
||||||
|
{
|
||||||
|
availableApplications.length !== 0 && <div className="">{renderFirstLayerItems()}</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
availableApplications.length === 0 && <div>
|
||||||
|
<div className="flex justify-center items-center h-full">
|
||||||
|
<div className="text-center text-gray-500 dark:text-gray-400">
|
||||||
|
<p className="text-sm">No menu items available</p>
|
||||||
|
<p className="text-xs mt-1">Please check your permissions or contact an administrator</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MenuItemsSection;
|
export default MenuItemsSection;
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,26 @@ interface Props {
|
||||||
selectedItem: any;
|
selectedItem: any;
|
||||||
refreshSelection: () => Promise<void>;
|
refreshSelection: () => Promise<void>;
|
||||||
updateSelection: (newSelection: any) => Promise<boolean>;
|
updateSelection: (newSelection: any) => Promise<boolean>;
|
||||||
|
refreshMenu: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectFromSelectionList = (item: any, selectedItem: any, updateSelection: (newSelection: any) => Promise<boolean>, refreshSelection: () => Promise<void>) => {
|
const selectFromSelectionList = async (item: any, selectedItem: any, updateSelection: (newSelection: any) => Promise<boolean>, refreshSelection: () => Promise<void>, refreshMenu: () => Promise<void>) => {
|
||||||
const selectedUUID = selectedItem?.uu_id || selectedItem?.build_living_space_uu_id;
|
const selectedUUID = selectedItem?.uu_id || selectedItem?.build_living_space_uu_id;
|
||||||
const itemUUID = item?.uu_id || item?.build_living_space_uu_id;
|
const itemUUID = item?.uu_id || item?.build_living_space_uu_id;
|
||||||
if (selectedUUID !== itemUUID) { updateSelection(item); refreshSelection() }
|
if (selectedUUID !== itemUUID) {
|
||||||
|
// First update the selection
|
||||||
|
await updateSelection(item);
|
||||||
|
// Then refresh the selection
|
||||||
|
await refreshSelection();
|
||||||
|
// Wait a moment to ensure the selection update is processed
|
||||||
|
setTimeout(async () => {
|
||||||
|
// Finally refresh the menu
|
||||||
|
await refreshMenu();
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const RenderOneClientSelection: FC<Props> = ({ item, selectedItem, updateSelection, refreshSelection }) => {
|
const RenderOneClientSelection: FC<Props> = ({ item, selectedItem, updateSelection, refreshSelection, refreshMenu }) => {
|
||||||
const selectedUUID = selectedItem?.uu_id || selectedItem?.build_living_space_uu_id;
|
const selectedUUID = selectedItem?.uu_id || selectedItem?.build_living_space_uu_id;
|
||||||
const itemUUID = item?.uu_id || item?.build_living_space_uu_id;
|
const itemUUID = item?.uu_id || item?.build_living_space_uu_id;
|
||||||
const getDisplayName = () => { if (item.public_name) return item.public_name; if (item.part_name) return item.part_name; return "No Name" };
|
const getDisplayName = () => { if (item.public_name) return item.public_name; if (item.part_name) return item.part_name; return "No Name" };
|
||||||
|
|
@ -24,7 +35,7 @@ const RenderOneClientSelection: FC<Props> = ({ item, selectedItem, updateSelecti
|
||||||
|
|
||||||
if (selectedUUID !== itemUUID) {
|
if (selectedUUID !== itemUUID) {
|
||||||
return (
|
return (
|
||||||
<div key={itemUUID} onClick={() => { selectFromSelectionList(item, selectedItem, updateSelection, refreshSelection) }}
|
<div key={itemUUID} onClick={() => { selectFromSelectionList(item, selectedItem, updateSelection, refreshSelection, refreshMenu) }}
|
||||||
className="w-full text-xs bg-white shadow rounded-lg overflow-hidden transition-all hover:shadow-md mb-2 cursor-pointer">
|
className="w-full text-xs bg-white shadow rounded-lg overflow-hidden transition-all hover:shadow-md mb-2 cursor-pointer">
|
||||||
<div className="bg-amber-800 p-2 hover:bg-amber-900 transition-all">
|
<div className="bg-amber-800 p-2 hover:bg-amber-900 transition-all">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ interface UserProfileSectionProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const UserProfileSection: FC<UserProfileSectionProps> = ({ userData, onlineData, selectionData }) => {
|
const UserProfileSection: FC<UserProfileSectionProps> = ({ userData, onlineData, selectionData }) => {
|
||||||
console.log("selectionData", selectionData)
|
|
||||||
if (!selectionData?.activeSelection) return null;
|
if (!selectionData?.activeSelection) return null;
|
||||||
let selectionDefinitionFirst = "";
|
let selectionDefinitionFirst = "";
|
||||||
let selectionDefinitionSecond = "";
|
let selectionDefinitionSecond = "";
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ interface UseMenuResult {
|
||||||
export function useMenu(): UseMenuResult {
|
export function useMenu(): UseMenuResult {
|
||||||
const { data, availableItems, isLoading, error, refresh, update } =
|
const { data, availableItems, isLoading, error, refresh, update } =
|
||||||
useContextMenu();
|
useContextMenu();
|
||||||
|
console.log("data", data);
|
||||||
|
console.log("availableItems", availableItems);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
menuData: data,
|
menuData: data,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ const getMenuFromRedis = async (): Promise<ClientMenu> => {
|
||||||
} catch (error) { if (error instanceof AuthError) { throw error } else { throw new AuthError(error instanceof Error ? error.message : "Unknown error") } }
|
} catch (error) { if (error instanceof AuthError) { throw error } else { throw new AuthError(error instanceof Error ? error.message : "Unknown error") } }
|
||||||
}
|
}
|
||||||
|
|
||||||
const setMenuToRedis = async (menuObject: ClientMenu) => {
|
const setMenuToRedis = async (menuObject: string[]) => {
|
||||||
try {
|
try {
|
||||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||||
|
|
@ -26,7 +26,12 @@ const setMenuToRedis = async (menuObject: ClientMenu) => {
|
||||||
if (!menuObject) throw new AuthError("No menu object provided");
|
if (!menuObject) throw new AuthError("No menu object provided");
|
||||||
const oldData = await getCompleteFromRedis();
|
const oldData = await getCompleteFromRedis();
|
||||||
if (!oldData) throw new AuthError("No old data found in redis");
|
if (!oldData) throw new AuthError("No old data found in redis");
|
||||||
await setCompleteToRedis({ ...oldData, menu: menuObject });
|
await setCompleteToRedis({
|
||||||
|
...oldData, menu: {
|
||||||
|
...oldData.menu,
|
||||||
|
selectionList: menuObject,
|
||||||
|
}
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
} catch (error) { if (error instanceof AuthError) { throw error } else { throw new AuthError(error instanceof Error ? error.message : "Unknown error") } }
|
} catch (error) { if (error instanceof AuthError) { throw error } else { throw new AuthError(error instanceof Error ? error.message : "Unknown error") } }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import { retrievePageList } from "@/fetchers/mutual/cookies/token";
|
||||||
import { deleteAllCookies } from "@/fetchers/mutual/cookies/cookie-actions";
|
import { deleteAllCookies } from "@/fetchers/mutual/cookies/cookie-actions";
|
||||||
import { setMenuToRedis } from "@/fetchers/custom/context/page/menu/fetch";
|
import { setMenuToRedis } from "@/fetchers/custom/context/page/menu/fetch";
|
||||||
import { LoginViaAccessKeys, LoginSelect } from "@/fetchers/types/login/validations";
|
import { LoginViaAccessKeys, LoginSelect } from "@/fetchers/types/login/validations";
|
||||||
|
import { retrieveValidUrlsOfRestriction } from "../restriction/fetch";
|
||||||
|
|
||||||
async function logoutActiveSession() {
|
async function logoutActiveSession() {
|
||||||
const response = await fetchDataWithToken(urlLogoutEndpoint, {}, "GET", false);
|
const response = await fetchDataWithToken(urlLogoutEndpoint, {}, "GET", false);
|
||||||
|
|
@ -157,7 +158,8 @@ async function loginSelectEmployee(payload: LoginSelect) {
|
||||||
if (selectResponse.status === 200 || selectResponse.status === 202) {
|
if (selectResponse.status === 200 || selectResponse.status === 202) {
|
||||||
try {
|
try {
|
||||||
console.log("selectResponse", selectResponse) // Get Menu URL's of Employee
|
console.log("selectResponse", selectResponse) // Get Menu URL's of Employee
|
||||||
|
const validUrls = await retrieveValidUrlsOfRestriction()
|
||||||
|
setMenuToRedis(validUrls)
|
||||||
} catch (error) { }
|
} catch (error) { }
|
||||||
}
|
}
|
||||||
return selectResponse;
|
return selectResponse;
|
||||||
|
|
@ -169,6 +171,8 @@ async function loginSelectOccupant(payload: LoginSelect) {
|
||||||
if (selectResponse.status === 200 || selectResponse.status === 202) {
|
if (selectResponse.status === 200 || selectResponse.status === 202) {
|
||||||
try {
|
try {
|
||||||
console.log("selectResponse", selectResponse) // Get Menu URL's of Occupant
|
console.log("selectResponse", selectResponse) // Get Menu URL's of Occupant
|
||||||
|
const validUrls = await retrieveValidUrlsOfRestriction()
|
||||||
|
setMenuToRedis(validUrls)
|
||||||
} catch (error) { }
|
} catch (error) { }
|
||||||
}
|
}
|
||||||
return selectResponse;
|
return selectResponse;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
"use server";
|
||||||
|
import { fetchDataWithToken } from "@/fetchers/fecther";
|
||||||
|
import { fetchResponseStatus } from "@/fetchers/utils";
|
||||||
|
import { urlSiteUrls } from "@/fetchers/index";
|
||||||
|
|
||||||
|
async function retrieveValidUrlsOfRestriction() {
|
||||||
|
const response = await fetchDataWithToken(urlSiteUrls, {}, "GET", false);
|
||||||
|
if (!fetchResponseStatus(response)) throw new Error("No valid urls found");
|
||||||
|
const data = response.data as any;
|
||||||
|
return data.sites;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { retrieveValidUrlsOfRestriction }
|
||||||
Loading…
Reference in New Issue