update 13 files
This commit is contained in:
parent
d8404e219f
commit
95652f3f16
|
|
@ -120,9 +120,11 @@ export const ThumbPreview = ({
|
|||
export const FilePreview = ({
|
||||
url,
|
||||
disabled,
|
||||
limit_name,
|
||||
}: {
|
||||
url: any;
|
||||
disabled?: boolean;
|
||||
limit_name?: number;
|
||||
}) => {
|
||||
let ural = url;
|
||||
if (url instanceof File) {
|
||||
|
|
@ -172,7 +174,8 @@ export const FilePreview = ({
|
|||
const getFileNameWithoutExtension = (filename: string) => {
|
||||
const parts = filename.split(".");
|
||||
parts.pop(); // Hapus bagian terakhir (ekstensi)
|
||||
return parts.join("."); // Gabungkan kembali
|
||||
const result = parts.join("."); // Gabungkan kembali
|
||||
return limit_name ? result.substring(0, limit_name) : result;
|
||||
};
|
||||
const ura =
|
||||
ural && ural.startsWith("blob:") ? getFileNameWithoutExtension(ural) : ural;
|
||||
|
|
@ -234,7 +237,6 @@ export const FilePreview = ({
|
|||
onClick={() => {
|
||||
let _url: any =
|
||||
url && url.startsWith("blob:") ? ura : siteurl(ura || "");
|
||||
console.log(_url);
|
||||
window.open(_url, "_blank");
|
||||
}}
|
||||
>
|
||||
|
|
@ -302,7 +304,6 @@ const getFileName = (url: string) => {
|
|||
}
|
||||
|
||||
const fileName = url.substring(url.lastIndexOf("/") + 1);
|
||||
console.log({ fileName });
|
||||
const dotIndex = fileName.lastIndexOf(".");
|
||||
const fullname = fileName;
|
||||
if (dotIndex === -1) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import { useLocal } from "@/lib/utils/use-local";
|
||||
import { Typeahead } from "./Typeahead";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export const TypeDropdown: React.FC<any> = ({
|
||||
required,
|
||||
|
|
@ -45,7 +43,6 @@ export const TypeDropdown: React.FC<any> = ({
|
|||
if (typeof onChange === "function" && item) {
|
||||
onChange(item);
|
||||
}
|
||||
console.log(fm.data[name]);
|
||||
return item?.value || search;
|
||||
}}
|
||||
disabled={disabled}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { Textarea } from "../../ui/text-area";
|
|||
import { useEffect, useRef, useState } from "react";
|
||||
import tinycolor from "tinycolor2";
|
||||
import { FieldColorPicker } from "../../ui/FieldColorPopover";
|
||||
import { FaRegEye, FaRegEyeSlash, FaRegStar, FaStar } from "react-icons/fa6";
|
||||
import { FaRegEye, FaRegEyeSlash } from "react-icons/fa6";
|
||||
import { Rating } from "../../ui/ratings";
|
||||
import { getNumber } from "@/lib/utils/getNumber";
|
||||
import MaskedInput from "../../ui/MaskedInput";
|
||||
|
|
@ -50,6 +50,12 @@ export const TypeInput: React.FC<any> = ({
|
|||
textarea.style.height = `${textarea.scrollHeight}px`; // Adjust height based on content
|
||||
}
|
||||
};
|
||||
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (event.key === "Enter") {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (type === "color") {
|
||||
meta.inputValue = value || "";
|
||||
|
|
@ -153,40 +159,6 @@ export const TypeInput: React.FC<any> = ({
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<div className="flex">
|
||||
{Array.from({ length: 5 }, (_, index) => index + 1).map(
|
||||
(number) => (
|
||||
<button
|
||||
key={number}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleClick(number);
|
||||
}}
|
||||
onMouseEnter={() => setHover(number)} // Set nilai hover saat mouse masuk
|
||||
onMouseLeave={() => setHover(number)} // Reset nilai hover saat mouse keluar
|
||||
className={cx(
|
||||
"focus:outline-none px-0.5",
|
||||
disabled ? "" : "transition-transform duration-200"
|
||||
)}
|
||||
style={{
|
||||
transform:
|
||||
hover === number && !disabled ? "scale(1.2)" : "scale(1)",
|
||||
}}
|
||||
>
|
||||
{hover >= number || rating >= number ? (
|
||||
<FaStar className="text-yellow-400" /> // Star yang diisi (fill)
|
||||
) : (
|
||||
<FaRegStar className="text-gray-400" /> // Star yang kosong (outline)
|
||||
)}
|
||||
</button>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case "color":
|
||||
return (
|
||||
|
|
@ -287,6 +259,7 @@ export const TypeInput: React.FC<any> = ({
|
|||
placeholder={placeholder || ""}
|
||||
value={formatCurrency(input.value)}
|
||||
type={"text"}
|
||||
onKeyDown={handleKeyDown}
|
||||
onChange={(ev) => {
|
||||
const rawValue = ev.currentTarget.value
|
||||
.replace(/[^0-9,-]/g, "")
|
||||
|
|
@ -328,6 +301,7 @@ export const TypeInput: React.FC<any> = ({
|
|||
<>
|
||||
<Input
|
||||
id={name}
|
||||
onKeyDown={handleKeyDown}
|
||||
name={name}
|
||||
className={cx(
|
||||
"text-sm",
|
||||
|
|
|
|||
|
|
@ -172,22 +172,25 @@ export const FieldUploadSingle: FC<{
|
|||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div
|
||||
onClick={() => {
|
||||
if (input.ref) {
|
||||
input.ref.click();
|
||||
}
|
||||
}}
|
||||
className="items-center flex text-base px-1 outline-none rounded cursor-pointer flex-row justify-center"
|
||||
>
|
||||
<div className="flex flex-row items-center px-2">
|
||||
<Upload className="h-4 w-4" />
|
||||
{!disabled ? (
|
||||
<div
|
||||
onClick={() => {
|
||||
if (input.ref) {
|
||||
input.ref.click();
|
||||
}
|
||||
}}
|
||||
className="items-center flex text-base px-1 outline-none rounded cursor-pointer flex-row justify-center"
|
||||
>
|
||||
<div className="flex flex-row items-center px-2">
|
||||
<Upload className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex flex-row items-center text-sm">
|
||||
Add File
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row items-center text-sm">
|
||||
Add File
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-row items-center px-1.5 text-sm">-</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : input.fase === "upload" ? (
|
||||
|
|
|
|||
|
|
@ -128,7 +128,9 @@ const SidebarBetterTree: React.FC<TreeMenuProps> = ({
|
|||
}
|
||||
`,
|
||||
mini
|
||||
? isActive
|
||||
? isParentActive
|
||||
? "bg-linear-sidebar-active text-white font-normal p-1 shadow-md w-[50px]"
|
||||
: isActive
|
||||
? !depth
|
||||
? "bg-linear-sidebar-active text-white font-normal p-1 shadow-md"
|
||||
: " bg-layer text-primary font-bold p-1 "
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ export const TableList: React.FC<any> = ({
|
|||
selection: {
|
||||
all: false,
|
||||
partial: [] as any[],
|
||||
data: [] as any[],
|
||||
},
|
||||
renderRow: (row: any) => {
|
||||
setData((prev) => [...prev, row]);
|
||||
|
|
@ -156,7 +157,6 @@ export const TableList: React.FC<any> = ({
|
|||
local.render();
|
||||
fm.data[name] = local.data;
|
||||
fm.render();
|
||||
console.log(fm.data[name]);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
@ -210,14 +210,14 @@ export const TableList: React.FC<any> = ({
|
|||
paging: 1,
|
||||
});
|
||||
local.data = res;
|
||||
cloneListFM(res);
|
||||
if (mode === "form") cloneListFM(res);
|
||||
local.render();
|
||||
setData(res);
|
||||
setData(local.data);
|
||||
} else {
|
||||
local.data = onLoad;
|
||||
cloneListFM(onLoad);
|
||||
if (mode === "form") cloneListFM(onLoad);
|
||||
local.render();
|
||||
setData(onLoad);
|
||||
setData(local.data);
|
||||
}
|
||||
}
|
||||
setTimeout(() => {
|
||||
|
|
@ -237,20 +237,34 @@ export const TableList: React.FC<any> = ({
|
|||
{
|
||||
id: "select",
|
||||
width: 10,
|
||||
header: ({ table }) => (
|
||||
<Checkbox
|
||||
id="terms"
|
||||
className="text-white"
|
||||
checked={table.getIsAllRowsSelected()}
|
||||
onClick={(e) => {
|
||||
table.getToggleAllRowsSelectedHandler();
|
||||
const handler = table.getToggleAllRowsSelectedHandler();
|
||||
handler(e); // Pastikan ini memanggil fungsi handler yang benar
|
||||
local.selection.all = !local.selection.all;
|
||||
local.render();
|
||||
}}
|
||||
/>
|
||||
),
|
||||
header: ({ table }) => {
|
||||
return (
|
||||
<Checkbox
|
||||
id="terms"
|
||||
className="text-primary bg-white data-[state=checked]:bg-white data-[state=checked]:text-primary"
|
||||
checked={table.getIsAllRowsSelected()}
|
||||
onClick={(e) => {
|
||||
table.getToggleAllRowsSelectedHandler();
|
||||
const handler = table.getToggleAllRowsSelectedHandler();
|
||||
handler(e); // Pastikan ini memanggil fungsi handler yang benar
|
||||
local.selection.all = !local.selection.all;
|
||||
local.render();
|
||||
setTimeout(() => {
|
||||
if (!table.getIsAllRowsSelected()) {
|
||||
local.selection.all = false;
|
||||
local.selection.partial = [];
|
||||
local.selection.data = [];
|
||||
local.render();
|
||||
} else {
|
||||
local.selection.partial = local.data.map((e) => e?.id);
|
||||
local.selection.data = local.data;
|
||||
local.render();
|
||||
}
|
||||
}, 25);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const findCheck = (row: any) => {
|
||||
if (row.getIsSelected()) return true;
|
||||
|
|
@ -262,6 +276,7 @@ export const TableList: React.FC<any> = ({
|
|||
<div className="px-0.5 items-center justify-center flex flex-row">
|
||||
<Checkbox
|
||||
id="terms"
|
||||
className="border border-primary"
|
||||
checked={findCheck(row)}
|
||||
onClick={(e) => {
|
||||
const handler = row.getToggleSelectedHandler();
|
||||
|
|
@ -272,6 +287,7 @@ export const TableList: React.FC<any> = ({
|
|||
: local.selection.partial.find((e) => e === data?.id);
|
||||
if (!checked) {
|
||||
local.selection.partial.push(data?.id);
|
||||
local.selection.data.push(data);
|
||||
} else {
|
||||
if (
|
||||
local.selection.partial.find((e) => e === data?.id)
|
||||
|
|
@ -280,6 +296,9 @@ export const TableList: React.FC<any> = ({
|
|||
local.selection.partial.filter(
|
||||
(e: any) => e !== data?.id
|
||||
);
|
||||
local.selection.data = local.selection.data.filter(
|
||||
(e: any) => e?.id !== data?.id
|
||||
);
|
||||
}
|
||||
local.selection.all = false;
|
||||
}
|
||||
|
|
@ -674,6 +693,10 @@ export const TableList: React.FC<any> = ({
|
|||
tbl: local,
|
||||
fm_row: fm_row,
|
||||
onChange,
|
||||
render: () => {
|
||||
local.render();
|
||||
setData(local.data);
|
||||
},
|
||||
};
|
||||
const head = column.find(
|
||||
(e: any) =>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { useLocal } from "@/lib/utils/use-local";
|
|||
import get from "lodash.get";
|
||||
import { TabHeaderBetter } from "../tablist/TabHeaderBetter";
|
||||
import { getNumber } from "@/lib/utils/getNumber";
|
||||
import { BreadcrumbBetterLink } from "../ui/breadcrumb-link";
|
||||
export const TableUI: React.FC<any> = ({
|
||||
name,
|
||||
column,
|
||||
|
|
@ -27,6 +28,7 @@ export const TableUI: React.FC<any> = ({
|
|||
title,
|
||||
tab,
|
||||
onTab,
|
||||
breadcrumb,
|
||||
}) => {
|
||||
const local = useLocal({
|
||||
tab: get(tab, "[0].id"),
|
||||
|
|
@ -34,8 +36,13 @@ export const TableUI: React.FC<any> = ({
|
|||
|
||||
return (
|
||||
<div className="flex flex-col flex-grow">
|
||||
<div className="w-full flex flex-row p-4 py-6 pr-6 pl-3 text-2xl font-bold">
|
||||
{title}
|
||||
<div className="w-full p-4 py-6 pr-6 pl-3 ">
|
||||
<div className="flex flex-row text-2xl font-bold">{title}</div>
|
||||
{breadcrumb?.length ? (
|
||||
<BreadcrumbBetterLink data={breadcrumb} />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col flex-grow bg-card-layer rounded-lg border border-gray-300 shadow-md shadow-gray-300 overflow-hidden">
|
||||
<div className="flex flex-col flex-grow">
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {
|
|||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "./alert-dialog";
|
||||
import { X } from "lucide-react";
|
||||
|
||||
export const Alert: FC<any> = ({
|
||||
type,
|
||||
|
|
@ -35,7 +34,9 @@ export const Alert: FC<any> = ({
|
|||
) : (
|
||||
<>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||
<AlertDialogTitle>
|
||||
Are you certain you want to continue?
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{msg || message?.[type]}
|
||||
</AlertDialogDescription>
|
||||
|
|
|
|||
|
|
@ -61,11 +61,12 @@ const ButtonBetter = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|||
const ButtonLink: FC<any> = ({
|
||||
className,
|
||||
children,
|
||||
target,
|
||||
href,
|
||||
variant = "default",
|
||||
}) => {
|
||||
return (
|
||||
<Link href={href}>
|
||||
<Link href={href} target={target}>
|
||||
<ButtonBetter className={cx(className)} variant={variant}>
|
||||
{children}
|
||||
</ButtonBetter>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "./tooltip";
|
||||
import { ButtonLink } from "./button-link";
|
||||
|
||||
const btn = cva(
|
||||
" text-white px-4 py-1.5 group active-menu-icon relative flex items-stretch justify-center p-0.5 text-center border border-transparent text-white enabled:hover:bg-cyan-800 rounded-md"
|
||||
|
|
@ -50,6 +51,8 @@ export interface ButtonProps
|
|||
VariantProps<typeof buttonVariants> {
|
||||
asChild?: boolean;
|
||||
tooltip?: any;
|
||||
href?: string;
|
||||
typeButton?: "button" | "container" | "tooltip";
|
||||
}
|
||||
|
||||
const ButtonBetter = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
|
|
@ -65,18 +68,49 @@ const ButtonBetter = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|||
}
|
||||
);
|
||||
const ButtonBetterTooltip = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ tooltip, className, variant, size, asChild = false, ...props }, ref) => {
|
||||
(
|
||||
{
|
||||
typeButton = "button",
|
||||
tooltip,
|
||||
href,
|
||||
className,
|
||||
variant,
|
||||
size,
|
||||
asChild = false,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const Comp = asChild ? Slot : "button";
|
||||
if (tooltip) {
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Comp
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
<div className="flex flex-row items-center">
|
||||
{href ? (
|
||||
<ButtonLink
|
||||
href={href}
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
ref={ref}
|
||||
variant={variant}
|
||||
>
|
||||
{props.children}
|
||||
</ButtonLink>
|
||||
) : typeButton === "container" ? (
|
||||
<ButtonContainer
|
||||
className={className}
|
||||
variant={variant}
|
||||
children={props.children}
|
||||
/>
|
||||
) : (
|
||||
<Comp
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="bg-linear-sidebar-active text-white border border-primary shadow-md transition-all ">
|
||||
<p>{tooltip}</p>
|
||||
|
|
@ -85,6 +119,27 @@ const ButtonBetterTooltip = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|||
</TooltipProvider>
|
||||
);
|
||||
}
|
||||
if (href) {
|
||||
return (
|
||||
<ButtonLink
|
||||
href={href}
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
ref={ref}
|
||||
variant={variant}
|
||||
>
|
||||
{props.children}
|
||||
</ButtonLink>
|
||||
);
|
||||
}
|
||||
if (typeButton === "container") {
|
||||
return (
|
||||
<ButtonContainer
|
||||
className={className}
|
||||
variant={variant}
|
||||
children={props.children}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Comp
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
|
|
@ -94,6 +149,7 @@ const ButtonBetterTooltip = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|||
);
|
||||
}
|
||||
);
|
||||
|
||||
const ButtonContainer: FC<any> = ({
|
||||
children,
|
||||
className,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
import { FC } from "react";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "./tooltip";
|
||||
|
||||
export const TooltipBetter: FC<any> = ({ content, children }) => {
|
||||
if (content) {
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div className="w-full flex flex-grow flex-row">{children}</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="bg-linear-sidebar-active text-white border border-primary shadow-md transition-all ">
|
||||
<p>{content}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
);
|
||||
}
|
||||
return children;
|
||||
};
|
||||
|
|
@ -12,7 +12,6 @@ export const longDate = (date: string | Date) => {
|
|||
};
|
||||
|
||||
export const dayDate = (date: string | Date) => {
|
||||
console.log({ date });
|
||||
if (date instanceof Date || (typeof date === "string" && !empty(date))) {
|
||||
return day(date).format("DD MMMM YYYY");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import get from "lodash.get";
|
||||
import { get_user } from "./get_user";
|
||||
import api from "./axios";
|
||||
|
||||
export const getAccess = (keys: string, data: any[]) => {
|
||||
|
|
@ -15,6 +14,20 @@ export const getAccess = (keys: string, data: any[]) => {
|
|||
return false;
|
||||
};
|
||||
|
||||
export const access = (keys: string) => {
|
||||
const data = globalThis.userRole;
|
||||
if (!Array.isArray(data) || !data?.length) return false;
|
||||
for (const role of data) {
|
||||
const permissionExists = role.permissions.some(
|
||||
(permission: any) => get(permission, "name") === keys
|
||||
);
|
||||
if (permissionExists) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const userRoleMe = async (w?: boolean) => {
|
||||
let user = null as any;
|
||||
let data = null as any;
|
||||
|
|
|
|||
Loading…
Reference in New Issue