diff --git a/comps/charts/bar.tsx b/comps/charts/bar.tsx index 30b344a..e4a67e4 100755 --- a/comps/charts/bar.tsx +++ b/comps/charts/bar.tsx @@ -1,4 +1,4 @@ -import { useLocal } from "lib/utils/use-local"; +import { useLocal } from "@/utils/use-local"; import { FC, useEffect } from "react"; import { loadChart } from "./loader"; import type { Bar } from "react-chartjs-2"; @@ -14,8 +14,9 @@ const getRandomInt = (min: number, max: number) => { export const BarChart: FC<{ data: () => ItemData; - legend?: any -}> = ({ data, legend }) => { + legend?: any; + scale?: any; +}> = ({ data, legend, scale }) => { const local = useLocal({ data: null as unknown as ItemData, Bar: null as null | typeof Bar, @@ -42,6 +43,7 @@ export const BarChart: FC<{ options={{ responsive: true, maintainAspectRatio: false, + scales: scale, plugins: legend === "none" ? { diff --git a/comps/custom/Datepicker/components/Calendar/Days.tsx b/comps/custom/Datepicker/components/Calendar/Days.tsx index f4e75ac..4ee0b9a 100755 --- a/comps/custom/Datepicker/components/Calendar/Days.tsx +++ b/comps/custom/Datepicker/components/Calendar/Days.tsx @@ -415,10 +415,10 @@ const Days: React.FC = ({ hoverDay(item, "previous"); }} > - - {item} - {load_marker(item, "previous")} - + + {item} + {load_marker(item, "previous")} + ))} @@ -438,7 +438,7 @@ const Days: React.FC = ({ > {item} - {load_marker(item, "current")} + {load_marker(item, "current")} ))} @@ -454,10 +454,10 @@ const Days: React.FC = ({ hoverDay(item, "next"); }} > - - {item} - {load_marker(item, "next")} - + + {item} + {load_marker(item, "next")} + ))} diff --git a/comps/custom/QrReader.tsx b/comps/custom/QrReader.tsx index 307dab8..7626d8b 100755 --- a/comps/custom/QrReader.tsx +++ b/comps/custom/QrReader.tsx @@ -1,76 +1,90 @@ -import { useEffect, useRef, useState } from "react"; +import { FC, useEffect, useRef, useState } from "react"; import QrScanner from "qr-scanner"; -export const QrReader = () => { - const scanner = useRef(); - const videoEl = useRef(null); - const qrBoxEl = useRef(null); - const [qrOn, setQrOn] = useState(true); - const [scannedResult, setScannedResult] = useState(""); +export const QrReader: FC<{ url: string }> = ({ url }) => { + const scanner = useRef(); + const videoEl = useRef(null); + const qrBoxEl = useRef(null); + const [qrOn, setQrOn] = useState(true); + const [scannedResult, setScannedResult] = useState(""); + const [hasScanned, setHasScanned] = useState(false); - // Success - const onScanSuccess = (result: QrScanner.ScanResult) => { - console.log(result); - setScannedResult(result?.data); - }; - // Fail - const onScanFail = (err: string | Error) => { - console.log(err); - }; + // Success + const onScanSuccess = (result: QrScanner.ScanResult) => { + // console.log(result); + // navigate("/hasil/scan"); + // setScannedResult(result?.data); + if (!hasScanned) { + console.log(result); + setScannedResult(result?.data); + setHasScanned(true); + scanner.current?.stop(); - useEffect(() => { - if (videoEl?.current && !scanner.current) { - scanner.current = new QrScanner(videoEl?.current, onScanSuccess, { - onDecodeError: onScanFail, - preferredCamera: "environment", - highlightScanRegion: true, - highlightCodeOutline: true, - overlay: qrBoxEl?.current || undefined, - }); - - scanner?.current - ?.start() - .then(() => setQrOn(true)) - .catch((err) => { - if (err) setQrOn(false); - }); - } - - return () => { - if (!videoEl?.current) { - scanner?.current?.stop(); - } + setTimeout(() => { + // console.log("Mencoba trigger hasil scan"); + // navigate(`/hasil/scan?id_asset=${result?.data}`); + navigate(url + result?.data); + }, 1000); + } }; - }, []); - useEffect(() => { - if (!qrOn) - alert( - "Camera is blocked or not accessible. Please allow camera in your browser permissions and Reload." - ); - }, [qrOn]); + // Fail + const onScanFail = (err: string | Error) => { + console.log(err); + }; - return ( -
- {/* QR */} - -
+ useEffect(() => { + if (videoEl?.current && !scanner.current) { + scanner.current = new QrScanner(videoEl?.current, onScanSuccess, { + onDecodeError: onScanFail, + preferredCamera: "environment", + highlightScanRegion: true, + highlightCodeOutline: true, + overlay: qrBoxEl?.current || undefined, + }); - {/* Show Data Result if scan is success */} - {scannedResult && ( -

- Scanned Result: {scannedResult} -

- )} -
- ); + scanner?.current + ?.start() + .then(() => setQrOn(true)) + .catch((err) => { + if (err) setQrOn(false); + }); + } + + return () => { + if (!videoEl?.current) { + scanner?.current?.stop(); + } + }; + }, []); + + useEffect(() => { + if (!qrOn) + alert( + "Kamera tidak bisa diakses. Tolong beri izin untuk akses kamera dan silahkan reload." + ); + }, [qrOn]); + + return ( +
+ +
+ +
+ {scannedResult && ( +

+ Scanned Result: {scannedResult} +

+ )} +
+ ); }; diff --git a/comps/dialog/Dialog.tsx b/comps/dialog/Dialog.tsx index 08106f4..682d968 100755 --- a/comps/dialog/Dialog.tsx +++ b/comps/dialog/Dialog.tsx @@ -1,4 +1,5 @@ -import * as DialogPrimitive from "@radix-ui/react-dialog"; +import { useLocal } from "@/utils/use-local"; +import { Button } from "lib/comps/ui/button"; import { Dialog, DialogContent, @@ -7,9 +8,9 @@ import { DialogTitle, DialogTrigger, } from "lib/comps/ui/dialog"; -import { useLocal } from "lib/utils/use-local"; +import * as DialogPrimitive from "@radix-ui/react-dialog"; import { X } from "lucide-react"; -import { FC } from "react"; +import { FC, useEffect } from "react"; export const Pop: FC<{ child: any; @@ -53,6 +54,7 @@ export const Pop: FC<{ )} /> +
{ local.open = false; @@ -62,6 +64,7 @@ export const Pop: FC<{ "c-absolute c-right-4 c-top-4 c-rounded-sm c-opacity-70 c-ring-offset-background c-transition-opacity hover:c-opacity-100 focus:c-outline-none focus:c-ring-2 focus:c-ring-ring focus:c-ring-offset-2 disabled:c-pointer-events-none data-[state=open]:c-bg-accent data-[state=open]:c-text-muted-foreground", css` right: 1rem; + z-index: 1; ` )} > @@ -85,6 +88,7 @@ export const Pop: FC<{ > {content} +
); diff --git a/comps/filter/FilterContent.tsx b/comps/filter/FilterContent.tsx index 8e4ecc7..0c66963 100755 --- a/comps/filter/FilterContent.tsx +++ b/comps/filter/FilterContent.tsx @@ -3,7 +3,7 @@ import { BaseForm } from "../form/base/BaseForm"; import { FilterLocal } from "./utils/types"; import { useLocal } from "lib/utils/use-local"; import { getFilter } from "./utils/get-filter"; -import { FMLocal } from "../form/typings"; +import { FieldLoading, FMLocal } from "lib/exports"; export const FilterContent: FC<{ mode: string; @@ -106,32 +106,37 @@ export const FilterContent: FC<{ { + const fm = form.fm; try { if (typeof form.fm?.data === "object") { - const fm = form.fm?.data as any form.render(); form.fm.render(); } } catch (ex) {} - if (typeof onSubmit === "function" && mode === "raw") { - const data = await onSubmit(form.fm); - if (typeof form.fm?.data === "object") { - form.fm.data = { - __status: "submit", - ...form.fm.data, - _where: data, - }; - form.fm.render(); - filter.data = { - __status: "submit", - ...form.fm.data, - _where: data, - }; - filter.render(); - } + if (mode === "raw" && fm) { + const submit = async (fm: FMLocal) => { + fm.render(); + if (typeof onSubmit === "function") { + const data = await onSubmit(fm); + if (typeof form.fm?.data === "object") { + form.fm.data = { + __status: "submit", + ...form.fm.data, + _where: data, + }; + form.fm.render(); + filter.data = { + __status: "submit", + ...form.fm.data, + _where: data, + }; + filter.render(); + } + } + }; + await submit(fm); } - // form.render(); const f = getFilter(filter.name); if (f) { for (const list of Object.values(f.list.ref)) { diff --git a/comps/filter/FilterField.tsx b/comps/filter/FilterField.tsx index 17b8a89..6425ffc 100755 --- a/comps/filter/FilterField.tsx +++ b/comps/filter/FilterField.tsx @@ -88,14 +88,14 @@ export const FilterField: FC<{ value={field.fm?.data?.[name]} placeholder={field.field.label} onBlur={() => { - clearTimeout(internal.search_timeout); - filter.form?.submit(); + // clearTimeout(internal.search_timeout); + // filter.form?.submit(); }} spellCheck={false} className="c-flex-1 c-transition-all c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full" onChange={(e) => { + console.log("HALO") field.fm.data[name] = e.currentTarget.value; - clearTimeout(internal.search_timeout); internal.search_timeout = setTimeout(() => { filter.form?.submit(); diff --git a/comps/filter/MasterFilter.tsx b/comps/filter/MasterFilter.tsx index 40da57b..3ef68f6 100755 --- a/comps/filter/MasterFilter.tsx +++ b/comps/filter/MasterFilter.tsx @@ -1,10 +1,10 @@ -import { useLocal } from "lib/utils/use-local"; -import { FC, ReactNode } from "react"; +import { useLocal } from "@/utils/use-local"; +import { FC, ReactNode, useEffect } from "react"; import { FMLocal, GenField } from "../form/typings"; import { FilterContent } from "./FilterContent"; import { getFilter } from "./utils/get-filter"; import { default_filter_local } from "./utils/types"; -import { FieldLoading } from "../ui/field-loading"; +import { FieldLoading } from "lib/exports"; type FilterMode = "raw" | "inline"; @@ -39,31 +39,42 @@ export const MasterFilter: FC = ({ const filter = useLocal({ ...default_filter_local }); filter.name = name; filter.mode = mode; - - if (!isEditor) { - const wf = getFilter(name); - if (wf) { - if (wf.filter.ref[_item.id]) { - filter.data = wf.filter.ref[_item.id].data; - } else { - if (mode === "raw" && onLoad) { - if (filter.raw_status === "init") { - filter.raw_status = "loading"; - filter.data = onLoad(); - filter.raw_status = "ready"; - filter.render(); - } - - if (filter.raw_status !== "ready") { - return ; + useEffect(() => { + if (!isEditor) { + const wf = getFilter(name); + if (wf) { + if (wf.filter.ref[_item.id]) { + filter.data = wf.filter.ref[_item.id].data; + filter.raw_status = "ready"; + filter.render(); + } else { + if (mode === "raw" && onLoad) { + if (filter.raw_status === "init") { + filter.raw_status = "loading"; + const data = onLoad(); + if (data instanceof Promise) { + data.then((e) => { + filter.data = e; + filter.raw_status = "ready"; + filter.render(); + }); + } else { + filter.raw_status = "ready"; + filter.data = data; + filter.render(); + } + } } } + wf.filter.ref[_item.id] = filter; + wf.list.render(); } - wf.filter.ref[_item.id] = filter; - wf.list.render(); } - } + }, []); + if (mode === "raw" && filter.raw_status !== "ready") { + return ; + } return ( <> { - console.log({ value }); + // console.log({ value }); fm.data[field.name] = value?.startDate ? new Date(value?.startDate) : null; diff --git a/comps/list/ImportExcel.tsx b/comps/list/ImportExcel.tsx index ff7bfd7..f4b7100 100755 --- a/comps/list/ImportExcel.tsx +++ b/comps/list/ImportExcel.tsx @@ -1,5 +1,5 @@ -import { GFCol } from "lib/gen/utils"; -import { useLocal } from "lib/utils/use-local"; +import { GFCol } from "@/gen/utils"; +import { useLocal } from "@/utils/use-local"; import { ChangeEvent, FC, MouseEvent } from "react"; // import { Workbook } from 'exceljs'; // import * as XLSX from "xlsx"; @@ -131,11 +131,7 @@ export const ImportExcel: FC = ({ }); rowIndex++; - // let insertedData = await table.create({ data: insertRow }); - // local.insertedData.push({ - // pk: insertedData.id, - // rows: insertedData - // }); + local.insertedData.push({ pk: insertRow[pk], rows: insertRow, diff --git a/comps/md/utils/md-hash.ts b/comps/md/utils/md-hash.ts index 70a381d..824b4c3 100755 --- a/comps/md/utils/md-hash.ts +++ b/comps/md/utils/md-hash.ts @@ -1,4 +1,4 @@ -import { fetchLinkParams, parseLink } from "lib/utils/fetch-link-params"; +import { fetchLinkParams, parseLink } from "lib/comps/form/field/type/TypeLink"; import { MDLocal } from "./typings"; import { BreadItem } from "lib/comps/custom/Breadcrumb"; @@ -37,7 +37,7 @@ export const masterDetailParseHash = (md: MDLocal) => { } } - if (changed) { + if (changed) { md.params.links = []; md.header.loading = true; fetchLinkParams(parsed_link).then((links) => { @@ -60,7 +60,7 @@ export const masterDetailApplyParams = (md: MDLocal) => { delete md.params.tabs[md.name]; } } - +console.log({select: JSON.parse(JSON.stringify(md.selected))}) const pk = md.pk; if (pk && row[pk.name]) { md.params.hash[md.name] = row[pk.name]; @@ -80,6 +80,18 @@ export const masterDetailApplyParams = (md: MDLocal) => { if (!isEditor) { location.hash = hash; } + if(!isEditor){ + if(md.props.tab_mode === "v-tab" || md.props.tab_mode === "h-tab"){ + try{ + if(row && md?.childs?.form?.fm && md?.childs?.form?.fm?.status === "ready" && md.selected?.id){ + md.childs.form.fm.reload(); + // console.log("MASUK???") + } + }catch(ex){ + + } + } + } }; const cleanHash = (hash: string) => { diff --git a/comps/sheet/sheet.tsx b/comps/sheet/sheet.tsx index 5b80125..8352dff 100755 --- a/comps/sheet/sheet.tsx +++ b/comps/sheet/sheet.tsx @@ -1,4 +1,4 @@ -import { useLocal } from "lib/utils/use-local"; +import { useLocal } from "@/utils/use-local"; import * as SheetPrimitive from "@radix-ui/react-dialog"; import { X } from "lucide-react"; import { FC, useEffect } from "react"; @@ -21,7 +21,22 @@ export const SheetCn: FC<{ content: any; header: string; open: string; -}> = ({ child, PassProp, props, content, header, open }) => { + close?: string; + mode?: "full" | "normal"; + direction?: "left" | "right" | "bottom" | "top"; + deps?: any; +}> = ({ + child, + PassProp, + props, + content, + header, + open, + close, + mode, + direction, + deps +}) => { const local = useLocal({ open: false, }); @@ -40,6 +55,7 @@ export const SheetCn: FC<{
{ local.open = true; local.render(); @@ -71,39 +87,60 @@ export const SheetCn: FC<{ )} /> - { - local.open = false; - local.render(); - }} - className={cx( - "c-absolute c-right-4 c-top-4 c-rounded-sm c-opacity-70 c-ring-offset-background c-transition-opacity hover:c-opacity-100 focus:c-outline-none focus:c-ring-2 focus:c-ring-ring focus:c-ring-offset-2 disabled:c-pointer-events-none data-[state=open]:c-bg-accent data-[state=open]:c-text-muted-foreground", - css` - right: 1rem; - ` - )} - > - - Close - - - {header} - + {close !== "n" ? ( + { + local.open = false; + local.render(); + }} + className={cx( + "c-absolute c-right-4 c-top-4 c-rounded-sm c-opacity-70 c-ring-offset-background c-transition-opacity hover:c-opacity-100 focus:c-outline-none focus:c-ring-2 focus:c-ring-ring focus:c-ring-offset-2 disabled:c-pointer-events-none data-[state=open]:c-bg-accent data-[state=open]:c-text-muted-foreground", + css` + right: 1rem; + z-index: 99; + ` + )} + > + + Close + + ) : ( + <> + )} + {header !== "" && header ? ( + + {header} + + ) : ( + <> + + + + )} + { local.open = true; local.render(); diff --git a/comps/ui/sheet.tsx b/comps/ui/sheet.tsx index ec94409..e2792fc 100755 --- a/comps/ui/sheet.tsx +++ b/comps/ui/sheet.tsx @@ -4,7 +4,7 @@ import * as React from "react"; import * as SheetPrimitive from "@radix-ui/react-dialog"; import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "lib/utils"; +import { cn } from "@/utils"; const Sheet = SheetPrimitive.Root; @@ -30,7 +30,7 @@ const SheetOverlay = React.forwardRef< SheetOverlay.displayName = SheetPrimitive.Overlay.displayName; const sheetVariants = cva( - "c-fixed c-z-50 c-gap-4 c-bg-background c-p-6 c-shadow-lg c-transition c-ease-in-out data-[state=closed]:c-duration-300 data-[state=open]:c-duration-500 data-[state=open]:c-animate-in data-[state=closed]:c-animate-out", + "c-fixed c-z-50 c-gap-4 c-bg-background c-shadow-lg c-transition c-ease-in-out data-[state=closed]:c-duration-300 data-[state=open]:c-duration-500 data-[state=open]:c-animate-in data-[state=closed]:c-animate-out", { variants: { side: { @@ -39,7 +39,7 @@ const sheetVariants = cva( "c-inset-x-0 c-bottom-0 c-border-t data-[state=closed]:c-slide-out-to-bottom data-[state=open]:c-slide-in-from-bottom", left: "c-inset-y-0 c-left-0 c-h-full c-w-3/4 c-border-r data-[state=closed]:c-slide-out-to-left data-[state=open]:c-slide-in-from-left sm:c-max-w-sm", right: - "c-inset-y-0 c-right-0 c-h-full c-w-3/4 c-border-l data-[state=closed]:c-slide-out-to-right data-[state=open]:c-slide-in-from-right sm:c-max-w-sm", + "c-inset-y-0 c-right-0 c-h-full c-w-3/4 c-border-l data-[disabled]:c-bg-red-300 data-[state=closed]:c-slide-out-to-right data-[state=open]:c-slide-in-from-right sm:c-max-w-sm", }, }, defaultVariants: {