@dasidev/dasi-ui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +346 -0
- package/bin/dasi-cli.cjs +184 -0
- package/dist/date-selector-test-BlukYeWl.js +91 -0
- package/dist/favicon.ico +0 -0
- package/dist/html2canvas.esm-CKxSAI8P.js +4886 -0
- package/dist/img/brand/ic_pln.svg +12 -0
- package/dist/img/brand/mapp_power_logo.svg +21 -0
- package/dist/img/common/pltu_ulumbu_flores_ntt.jpeg +0 -0
- package/dist/index-BQSA2aPs.js +126556 -0
- package/dist/index.es-DQWt-PZn.js +5769 -0
- package/dist/index.es.js +11 -0
- package/dist/index.umd.js +8564 -0
- package/dist/informasi-gudang-BmoEy2RL.js +164 -0
- package/dist/informasi-gudang-DXfS46Nh.js +50 -0
- package/dist/purify.es-C-9oolON.js +546 -0
- package/dist/scripts/pdf.worker.min.js +29 -0
- package/dist/scripts/pdf.worker.min.mjs +29 -0
- package/dist/scripts/pdf.worker.mjs +57722 -0
- package/dist/scripts/pdf.worker.mjs.map +1 -0
- package/dist/style.css +1 -0
- package/dist/test-schema-JFghGc0_.js +8 -0
- package/dist/test-schema-uusFsJe4.js +438 -0
- package/dist/types-l0sNRNKZ.js +1 -0
- package/package.json +178 -0
- package/src/App.vue +18 -0
- package/src/__tests__/index.test.ts +9 -0
- package/src/api/api.ts +117 -0
- package/src/assets/app-selector.svg +3 -0
- package/src/assets/dasi.png +0 -0
- package/src/assets/foto_ss.svg +21 -0
- package/src/assets/icons/circle-blue.svg +4 -0
- package/src/assets/icons/circle-gray.svg +15 -0
- package/src/assets/icons/circle-green.svg +4 -0
- package/src/assets/icons/circle-orange.svg +4 -0
- package/src/assets/icons/circle-purple.svg +4 -0
- package/src/assets/icons/circle-red.svg +15 -0
- package/src/assets/icons/harbor.svg +12 -0
- package/src/assets/icons/ic-box-red.svg +8 -0
- package/src/assets/icons/ic-chevron-right.svg +1 -0
- package/src/assets/icons/ic-loading.svg +9 -0
- package/src/assets/icons/ic-reset.svg +16 -0
- package/src/assets/icons/ic-sailing.svg +5 -0
- package/src/assets/icons/icon-app-selector.svg +3 -0
- package/src/assets/icons/icon-browser-check.svg +4 -0
- package/src/assets/icons/icon-calendar.svg +3 -0
- package/src/assets/icons/icon-chart-bar.svg +3 -0
- package/src/assets/icons/icon-chart-doc.svg +16 -0
- package/src/assets/icons/icon-chart-line.svg +10 -0
- package/src/assets/icons/icon-chart-mix.svg +15 -0
- package/src/assets/icons/icon-chart-pie.svg +11 -0
- package/src/assets/icons/icon-continue.svg +12 -0
- package/src/assets/icons/icon-dashboard-2.svg +17 -0
- package/src/assets/icons/icon-dashboard.svg +3 -0
- package/src/assets/icons/icon-data-kelistrikan.svg +19 -0
- package/src/assets/icons/icon-data-sentral.svg +11 -0
- package/src/assets/icons/icon-database.svg +5 -0
- package/src/assets/icons/icon-desktop.svg +3 -0
- package/src/assets/icons/icon-download.svg +13 -0
- package/src/assets/icons/icon-energi-primer.svg +12 -0
- package/src/assets/icons/icon-faba-apk2.svg +11 -0
- package/src/assets/icons/icon-faba.svg +11 -0
- package/src/assets/icons/icon-factory.svg +14 -0
- package/src/assets/icons/icon-globe-doc.svg +19 -0
- package/src/assets/icons/icon-ikk.svg +10 -0
- package/src/assets/icons/icon-kbb.svg +13 -0
- package/src/assets/icons/icon-kos.svg +16 -0
- package/src/assets/icons/icon-kpi-bod.svg +15 -0
- package/src/assets/icons/icon-kss.svg +14 -0
- package/src/assets/icons/icon-map.svg +12 -0
- package/src/assets/icons/icon-monitoring-harian.svg +13 -0
- package/src/assets/icons/icon-notification.svg +4 -0
- package/src/assets/icons/icon-overview.svg +17 -0
- package/src/assets/icons/icon-pltu.svg +13 -0
- package/src/assets/icons/icon-sebaran-sentral.svg +12 -0
- package/src/assets/icons/icon-select-data-kelistrikan.svg +19 -0
- package/src/assets/icons/icon-select-data-sentral.svg +11 -0
- package/src/assets/icons/icon-select-energi-primer.svg +12 -0
- package/src/assets/icons/icon-select-faba-apk2.svg +11 -0
- package/src/assets/icons/icon-select-ikk.svg +10 -0
- package/src/assets/icons/icon-select-kbb.svg +13 -0
- package/src/assets/icons/icon-select-kos.svg +16 -0
- package/src/assets/icons/icon-select-kpi-bod.svg +15 -0
- package/src/assets/icons/icon-select-kss.svg +14 -0
- package/src/assets/icons/icon-select-monitoring-harian.svg +13 -0
- package/src/assets/icons/icon-select-overview.svg +17 -0
- package/src/assets/icons/icon-select-sebaran-sentral.svg +12 -0
- package/src/assets/icons/icon-sentral-white.svg +13 -0
- package/src/assets/icons/icon-shipping.svg +5 -0
- package/src/assets/icons/icon-sort.svg +5 -0
- package/src/assets/icons/icon-tree-box.svg +14 -0
- package/src/assets/icons/icon-warehouse.svg +12 -0
- package/src/assets/icons/pin-green.svg +3 -0
- package/src/assets/icons/pin-orange.svg +3 -0
- package/src/assets/icons/pin-purple.svg +3 -0
- package/src/assets/icons/ship.svg +3 -0
- package/src/assets/icons/shipment/icon-antri.svg +15 -0
- package/src/assets/icons/shipment/icon-bongkar.svg +4 -0
- package/src/assets/icons/shipment/icon-invoice.svg +6 -0
- package/src/assets/icons/shipment/icon-loading.svg +8 -0
- package/src/assets/icons/shipment/icon-pembayaran.svg +13 -0
- package/src/assets/icons/shipment/icon-pengiriman.svg +4 -0
- package/src/assets/icons/shipment/icon-sailing.svg +4 -0
- package/src/assets/icons/shipment/icon-shipment-completed.svg +6 -0
- package/src/assets/icons/shipment/icon-shipment-in-progress.svg +6 -0
- package/src/assets/icons/shipment/icon-shipment-over-sla.svg +6 -0
- package/src/assets/icons/shipment/icon-spt.svg +4 -0
- package/src/assets/icons/shipment/icon-total-shipment.svg +4 -0
- package/src/assets/icons/upload_doc_icon.svg +42 -0
- package/src/assets/icons/upload_icon_blue.svg +14 -0
- package/src/assets/login-bg-day-min.jpg +0 -0
- package/src/assets/login-bg-night-min.jpg +0 -0
- package/src/assets/login-bg.jpg +0 -0
- package/src/assets/login-day.png +0 -0
- package/src/assets/login-night.png +0 -0
- package/src/assets/lucide-circle-plus-blue.svg +1 -0
- package/src/assets/pdf-logo.svg +11 -0
- package/src/assets/pemasok-card-bg.svg +6 -0
- package/src/assets/success_animation.gif +0 -0
- package/src/assets/success_animation.mp4 +0 -0
- package/src/assets/success_animation.webm +0 -0
- package/src/components/button/BtnAddOutline.vue +14 -0
- package/src/components/button/BtnCircle.vue +10 -0
- package/src/components/button/BtnOutline.vue +15 -0
- package/src/components/button/BtnPrimary.vue +25 -0
- package/src/components/button/BtnSecondary.vue +26 -0
- package/src/components/detail/AccountDetailTimeline.vue +144 -0
- package/src/components/detail/ApprovalInfo.vue +288 -0
- package/src/components/detail/DCI2.vue +164 -0
- package/src/components/detail/DetailContentHeader.vue +83 -0
- package/src/components/detail/DetailContentItem.vue +186 -0
- package/src/components/detail/DetailContentItems.vue +388 -0
- package/src/components/detail/DetailContentLoading.vue +12 -0
- package/src/components/detail/DetailContentTablet.vue +10 -0
- package/src/components/detail/DetailSheet.vue +294 -0
- package/src/components/detail/DetailTimeline.vue +191 -0
- package/src/components/detail/DocApprovalDialog.vue +29 -0
- package/src/components/detail/DocViewerContent.vue +991 -0
- package/src/components/dialog/ConfirmDialog.vue +96 -0
- package/src/components/dialog/DialogBase.vue +53 -0
- package/src/components/dialog/DialogSelect.vue +212 -0
- package/src/components/dialog/ErrorDialog.vue +63 -0
- package/src/components/dialog/FormDialog.vue +141 -0
- package/src/components/dialog/FormInputerDialog.vue +91 -0
- package/src/components/dialog/InfoDialog.vue +74 -0
- package/src/components/dialog/SuccessDialog.vue +51 -0
- package/src/components/examples/TestSchemaExample.vue +288 -0
- package/src/components/forms/auth/LoginForm.vue +806 -0
- package/src/components/forms/auth/PwdScore.vue +68 -0
- package/src/components/helper/ApiTester.vue +153 -0
- package/src/components/helper/ChangePwd.vue +150 -0
- package/src/components/helper/CheckboxElement.vue +43 -0
- package/src/components/helper/ConfigSwitcher.vue +54 -0
- package/src/components/helper/Copyright.vue +10 -0
- package/src/components/helper/ErrorScreen.vue +40 -0
- package/src/components/helper/LucideIcon.vue +27 -0
- package/src/components/helper/PdfViewer.vue +103 -0
- package/src/components/helper/PinInputer.vue +205 -0
- package/src/components/helper/PrivacyPolicy.vue +122 -0
- package/src/components/layout/PageActivityHeader.vue +48 -0
- package/src/components/layout/PageHeader.vue +70 -0
- package/src/components/loadings/LoadingDialog.vue +29 -0
- package/src/components/loadings/LoadingDialogSpin.vue +25 -0
- package/src/components/loadings/LoadingIndicator.vue +38 -0
- package/src/components/loadings/LoadingScreen.vue +23 -0
- package/src/components/notif/Notif.vue +103 -0
- package/src/components/notif/NotifItem.vue +41 -0
- package/src/components/pages/Header.vue +431 -0
- package/src/components/pages/Leftbar.vue +417 -0
- package/src/components/pages/PageActivity.vue +108 -0
- package/src/components/pages/PageActivityContent.vue +597 -0
- package/src/components/pages/PageContentTable.vue +589 -0
- package/src/components/pages/PageTab.vue +84 -0
- package/src/components/selector/BaseSelector.vue +1136 -0
- package/src/components/selector/ConfigDataSelector.vue +136 -0
- package/src/components/settings/SettingsItem.vue +38 -0
- package/src/components/tab/TabView.vue +11 -0
- package/src/components/tab/TabViewItem.vue +18 -0
- package/src/components/tab/TabViewItemBar.vue +9 -0
- package/src/components/tables/CellHover.vue +65 -0
- package/src/components/tables/DashboardDataTable.vue +707 -0
- package/src/components/tables/DataStatusTag.vue +52 -0
- package/src/components/tables/DataTable.vue +156 -0
- package/src/components/tables/DataTableAccordion.vue +249 -0
- package/src/components/tables/DataTableActionRow.vue +64 -0
- package/src/components/tables/DataTableCell.vue +272 -0
- package/src/components/tables/DataTableHeader.vue +60 -0
- package/src/components/tables/DataTableRow.vue +213 -0
- package/src/components/tables/ExpandedTable.vue +259 -0
- package/src/components/tables/PageTable.vue +73 -0
- package/src/components/tables/Pagination.vue +98 -0
- package/src/components/tables/dropdown/BaseDropdownTable.vue +140 -0
- package/src/components/tables/dropdown/DropdownTableActivity.vue +33 -0
- package/src/components/tables/dropdown/DropdownTableAsset.vue +30 -0
- package/src/components/tables/dropdown/DropdownTableConfig.vue +30 -0
- package/src/components/tables/dropdown/DropdownTableDataKonektor.vue +31 -0
- package/src/components/tables/dropdown/DropdownTableDataLabel.vue +30 -0
- package/src/components/tables/dropdown/DropdownTableDataSchema.vue +31 -0
- package/src/components/tables/dropdown/DropdownTableFabaPemanfaat.vue +30 -0
- package/src/components/tables/dropdown/DropdownTableGroup.vue +36 -0
- package/src/components/tables/dropdown/DropdownTableHalaman.vue +33 -0
- package/src/components/tables/dropdown/DropdownTableLevel.vue +66 -0
- package/src/components/tables/dropdown/DropdownTableOrganization.vue +47 -0
- package/src/components/tables/dropdown/DropdownTablePengelola.vue +28 -0
- package/src/components/tables/dropdown/DropdownTableQueryLayer.vue +29 -0
- package/src/components/tables/dropdown/DropdownTableSentral.vue +33 -0
- package/src/components/tables/dropdown/DropdownTableWarehouse.vue +30 -0
- package/src/components/tables/dropdown/TableDropdown.vue +52 -0
- package/src/components/ui/accordion/Accordion.vue +19 -0
- package/src/components/ui/accordion/AccordionContent.vue +24 -0
- package/src/components/ui/accordion/AccordionItem.vue +24 -0
- package/src/components/ui/accordion/AccordionTrigger.vue +42 -0
- package/src/components/ui/accordion/index.ts +4 -0
- package/src/components/ui/alert-dialog/AlertDialog.vue +14 -0
- package/src/components/ui/alert-dialog/AlertDialogAction.vue +20 -0
- package/src/components/ui/alert-dialog/AlertDialogCancel.vue +20 -0
- package/src/components/ui/alert-dialog/AlertDialogContent.vue +42 -0
- package/src/components/ui/alert-dialog/AlertDialogDescription.vue +25 -0
- package/src/components/ui/alert-dialog/AlertDialogFooter.vue +21 -0
- package/src/components/ui/alert-dialog/AlertDialogHeader.vue +16 -0
- package/src/components/ui/alert-dialog/AlertDialogTitle.vue +22 -0
- package/src/components/ui/alert-dialog/AlertDialogTrigger.vue +11 -0
- package/src/components/ui/alert-dialog/index.ts +9 -0
- package/src/components/ui/avatar/Avatar.vue +24 -0
- package/src/components/ui/avatar/AvatarFallback.vue +11 -0
- package/src/components/ui/avatar/AvatarImage.vue +9 -0
- package/src/components/ui/avatar/UsersAvatar.vue +28 -0
- package/src/components/ui/avatar/index.ts +24 -0
- package/src/components/ui/button/Button.vue +27 -0
- package/src/components/ui/button/index.ts +34 -0
- package/src/components/ui/calendar/Calendar.vue +325 -0
- package/src/components/ui/calendar/index.ts +22 -0
- package/src/components/ui/checkbox/Checkbox.vue +33 -0
- package/src/components/ui/checkbox/index.ts +1 -0
- package/src/components/ui/command/Command.vue +30 -0
- package/src/components/ui/command/CommandDialog.vue +21 -0
- package/src/components/ui/command/CommandEmpty.vue +20 -0
- package/src/components/ui/command/CommandGroup.vue +29 -0
- package/src/components/ui/command/CommandInput.vue +33 -0
- package/src/components/ui/command/CommandItem.vue +26 -0
- package/src/components/ui/command/CommandList.vue +27 -0
- package/src/components/ui/command/CommandSeparator.vue +23 -0
- package/src/components/ui/command/CommandShortcut.vue +14 -0
- package/src/components/ui/command/index.ts +9 -0
- package/src/components/ui/context-menu/ContextMenu.vue +15 -0
- package/src/components/ui/context-menu/ContextMenuCheckboxItem.vue +40 -0
- package/src/components/ui/context-menu/ContextMenuContent.vue +36 -0
- package/src/components/ui/context-menu/ContextMenuGroup.vue +11 -0
- package/src/components/ui/context-menu/ContextMenuItem.vue +34 -0
- package/src/components/ui/context-menu/ContextMenuLabel.vue +25 -0
- package/src/components/ui/context-menu/ContextMenuPortal.vue +11 -0
- package/src/components/ui/context-menu/ContextMenuRadioGroup.vue +19 -0
- package/src/components/ui/context-menu/ContextMenuRadioItem.vue +40 -0
- package/src/components/ui/context-menu/ContextMenuSeparator.vue +20 -0
- package/src/components/ui/context-menu/ContextMenuShortcut.vue +14 -0
- package/src/components/ui/context-menu/ContextMenuSub.vue +19 -0
- package/src/components/ui/context-menu/ContextMenuSubContent.vue +35 -0
- package/src/components/ui/context-menu/ContextMenuSubTrigger.vue +34 -0
- package/src/components/ui/context-menu/ContextMenuTrigger.vue +13 -0
- package/src/components/ui/context-menu/index.ts +14 -0
- package/src/components/ui/datetime/DatetimeRangeComponent.vue +52 -0
- package/src/components/ui/dialog/Dialog.vue +14 -0
- package/src/components/ui/dialog/DialogClose.vue +11 -0
- package/src/components/ui/dialog/DialogContent.vue +53 -0
- package/src/components/ui/dialog/DialogDescription.vue +24 -0
- package/src/components/ui/dialog/DialogFooter.vue +19 -0
- package/src/components/ui/dialog/DialogHeader.vue +16 -0
- package/src/components/ui/dialog/DialogScrollContent.vue +59 -0
- package/src/components/ui/dialog/DialogTitle.vue +29 -0
- package/src/components/ui/dialog/DialogTrigger.vue +11 -0
- package/src/components/ui/dialog/index.ts +9 -0
- package/src/components/ui/dropdown-menu/DropdownMenu.vue +14 -0
- package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +40 -0
- package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +38 -0
- package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
- package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +28 -0
- package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +24 -0
- package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +19 -0
- package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +41 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +22 -0
- package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +14 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +30 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +33 -0
- package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +13 -0
- package/src/components/ui/dropdown-menu/index.ts +16 -0
- package/src/components/ui/form/FormControl.vue +16 -0
- package/src/components/ui/form/FormDescription.vue +20 -0
- package/src/components/ui/form/FormItem.vue +25 -0
- package/src/components/ui/form/FormLabel.vue +23 -0
- package/src/components/ui/form/FormMessage.vue +16 -0
- package/src/components/ui/form/index.ts +6 -0
- package/src/components/ui/form/useFormField.ts +30 -0
- package/src/components/ui/hover-card/HoverCard.vue +14 -0
- package/src/components/ui/hover-card/HoverCardContent.vue +41 -0
- package/src/components/ui/hover-card/HoverCardTrigger.vue +11 -0
- package/src/components/ui/hover-card/index.ts +3 -0
- package/src/components/ui/input/Input.vue +24 -0
- package/src/components/ui/input/index.ts +1 -0
- package/src/components/ui/label/Label.vue +27 -0
- package/src/components/ui/label/index.ts +1 -0
- package/src/components/ui/pagination/PaginationEllipsis.vue +22 -0
- package/src/components/ui/pagination/PaginationFirst.vue +29 -0
- package/src/components/ui/pagination/PaginationLast.vue +29 -0
- package/src/components/ui/pagination/PaginationNext.vue +29 -0
- package/src/components/ui/pagination/PaginationPrev.vue +29 -0
- package/src/components/ui/pagination/index.ts +10 -0
- package/src/components/ui/pin-input/PinInput.vue +23 -0
- package/src/components/ui/pin-input/PinInputGroup.vue +18 -0
- package/src/components/ui/pin-input/PinInputInput.vue +18 -0
- package/src/components/ui/pin-input/PinInputSeparator.vue +15 -0
- package/src/components/ui/pin-input/index.ts +4 -0
- package/src/components/ui/popover/Popover.vue +15 -0
- package/src/components/ui/popover/PopoverContent.vue +48 -0
- package/src/components/ui/popover/PopoverTrigger.vue +11 -0
- package/src/components/ui/popover/index.ts +4 -0
- package/src/components/ui/preview/PreviewPdf.vue +118 -0
- package/src/components/ui/progress/ProgressCircle.vue +27 -0
- package/src/components/ui/progress/SemiCircularProgressBar.vue +83 -0
- package/src/components/ui/progress/TotalCalories.vue +31 -0
- package/src/components/ui/radio-group/RadioGroup.vue +25 -0
- package/src/components/ui/radio-group/RadioGroupItem.vue +37 -0
- package/src/components/ui/radio-group/index.ts +2 -0
- package/src/components/ui/scroll-area/ScrollArea.vue +29 -0
- package/src/components/ui/scroll-area/ScrollBar.vue +30 -0
- package/src/components/ui/scroll-area/index.ts +2 -0
- package/src/components/ui/select/Select.vue +15 -0
- package/src/components/ui/select/SelectContent.vue +52 -0
- package/src/components/ui/select/SelectGroup.vue +19 -0
- package/src/components/ui/select/SelectInline.vue +84 -0
- package/src/components/ui/select/SelectItem.vue +44 -0
- package/src/components/ui/select/SelectItemText.vue +11 -0
- package/src/components/ui/select/SelectLabel.vue +13 -0
- package/src/components/ui/select/SelectScrollDownButton.vue +24 -0
- package/src/components/ui/select/SelectScrollUpButton.vue +24 -0
- package/src/components/ui/select/SelectSeparator.vue +17 -0
- package/src/components/ui/select/SelectTrigger.vue +31 -0
- package/src/components/ui/select/SelectTriggerCustom.vue +23 -0
- package/src/components/ui/select/SelectValue.vue +11 -0
- package/src/components/ui/select/index.ts +12 -0
- package/src/components/ui/separator/Separator.vue +20 -0
- package/src/components/ui/separator/index.ts +1 -0
- package/src/components/ui/sheet/Sheet.vue +14 -0
- package/src/components/ui/sheet/SheetClose.vue +11 -0
- package/src/components/ui/sheet/SheetContent.vue +48 -0
- package/src/components/ui/sheet/SheetDescription.vue +22 -0
- package/src/components/ui/sheet/SheetFooter.vue +19 -0
- package/src/components/ui/sheet/SheetHeader.vue +16 -0
- package/src/components/ui/sheet/SheetTitle.vue +22 -0
- package/src/components/ui/sheet/SheetTrigger.vue +11 -0
- package/src/components/ui/sheet/index.ts +31 -0
- package/src/components/ui/skeleton/Skeleton.vue +28 -0
- package/src/components/ui/skeleton/index.ts +1 -0
- package/src/components/ui/sonner/Sonner.vue +22 -0
- package/src/components/ui/sonner/index.ts +1 -0
- package/src/components/ui/star/StarRating.vue +19 -0
- package/src/components/ui/switch/Switch.vue +37 -0
- package/src/components/ui/switch/index.ts +1 -0
- package/src/components/ui/table/Table.vue +16 -0
- package/src/components/ui/table/TableBody.vue +14 -0
- package/src/components/ui/table/TableCaption.vue +14 -0
- package/src/components/ui/table/TableCell.vue +21 -0
- package/src/components/ui/table/TableEmpty.vue +37 -0
- package/src/components/ui/table/TableFooter.vue +14 -0
- package/src/components/ui/table/TableHead.vue +14 -0
- package/src/components/ui/table/TableHeader.vue +14 -0
- package/src/components/ui/table/TableRow.vue +14 -0
- package/src/components/ui/table/index.ts +8 -0
- package/src/components/ui/tabs/Tabs.vue +15 -0
- package/src/components/ui/tabs/TabsContent.vue +22 -0
- package/src/components/ui/tabs/TabsList.vue +25 -0
- package/src/components/ui/tabs/TabsTrigger.vue +27 -0
- package/src/components/ui/tabs/index.ts +4 -0
- package/src/components/ui/tags-input/TagsInput.vue +22 -0
- package/src/components/ui/tags-input/TagsInputInput.vue +19 -0
- package/src/components/ui/tags-input/TagsInputItem.vue +22 -0
- package/src/components/ui/tags-input/TagsInputItemDelete.vue +24 -0
- package/src/components/ui/tags-input/TagsInputItemText.vue +19 -0
- package/src/components/ui/tags-input/index.ts +5 -0
- package/src/components/ui/textarea/Textarea.vue +24 -0
- package/src/components/ui/textarea/index.ts +1 -0
- package/src/components/ui/tooltip/Tooltip.vue +14 -0
- package/src/components/ui/tooltip/TooltipContent.vue +31 -0
- package/src/components/ui/tooltip/TooltipProvider.vue +11 -0
- package/src/components/ui/tooltip/TooltipTrigger.vue +11 -0
- package/src/components/ui/tooltip/index.ts +4 -0
- package/src/composables/useAppConfig.ts +332 -0
- package/src/composables/useDarkMode.ts +71 -0
- package/src/config/app.config.ts +318 -0
- package/src/config/examples/ecommerce.config.ts +132 -0
- package/src/config/examples/generic.config.ts +132 -0
- package/src/config/menu.config.ts +149 -0
- package/src/config/my-app.config.ts +134 -0
- package/src/config/test-config.ts +32 -0
- package/src/config/theme.config.ts +250 -0
- package/src/docs/index.ts +21 -0
- package/src/docs.scss +403 -0
- package/src/index.d.ts +5 -0
- package/src/index.ts +20 -0
- package/src/layouts/AuthLayout.vue +68 -0
- package/src/layouts/DefaultLayout.vue +119 -0
- package/src/layouts/DocsLayout.vue +681 -0
- package/src/layouts/FormGlobal.vue +50 -0
- package/src/layouts/GlobalDialog.vue +122 -0
- package/src/layouts/RakorConfirmDialog.vue +95 -0
- package/src/layouts/SettingsLayout.vue +115 -0
- package/src/lib/constants.ts +2 -0
- package/src/lib/detail.utils.ts +213 -0
- package/src/lib/form.utils.ts +1009 -0
- package/src/lib/page.flow.utils.ts +81 -0
- package/src/lib/page.utils.ts +865 -0
- package/src/lib/performance.utils.ts +302 -0
- package/src/lib/tablerow.utils.ts +51 -0
- package/src/lib/utils.ts +643 -0
- package/src/main.scss +717 -0
- package/src/main.ts +74 -0
- package/src/menu.ts +78 -0
- package/src/nestedlist_color.scss +161 -0
- package/src/router/index.ts +92 -0
- package/src/stores/auth.ts +117 -0
- package/src/stores/counter.ts +12 -0
- package/src/stores/dialog.ts +168 -0
- package/src/stores/form.ts +103 -0
- package/src/stores/tabs.ts +52 -0
- package/src/tw.scss +419 -0
- package/src/types/form.types.ts +348 -0
- package/src/types/types.ts +7 -0
- package/src/utils/config.utils.ts +149 -0
- package/src/views/NotFound.vue +30 -0
- package/src/views/PageActivity.vue +15 -0
- package/src/views/auth/LoginView.vue +7 -0
- package/src/views/auth/OauthCallback.vue +101 -0
- package/src/views/dashboard/index.vue +16 -0
- package/src/views/settings/AccountSettingsView.vue +70 -0
- package/src/views/settings/AuditLogsSettingsView.vue +116 -0
- package/src/views/settings/DeviceSettingsView.vue +70 -0
- package/src/views/settings/MainSettingsView.vue +12 -0
- package/src/views/settings/ProfileSettingsView.vue +104 -0
- package/src/vueform/config/informasi-gudang.ts +47 -0
- package/src/vueform/config/test-schema.ts +8 -0
- package/src/vueform/config/types.ts +768 -0
- package/src/vueform/customization/classes.js +46 -0
- package/src/vueform/customization/tailwind.classes.js +2117 -0
- package/src/vueform/elements/ConfigDataSelectorElement.vue +50 -0
- package/src/vueform/elements/DateSelectorElement.vue +323 -0
- package/src/vueform/elements/SelectorElement.vue +153 -0
- package/src/vueform/schemas/date-selector-test.ts +103 -0
- package/src/vueform/schemas/informasi-gudang.ts +160 -0
- package/src/vueform/schemas/test-schema.ts +483 -0
- package/src/vueform.config.js +77 -0
- package/src/vueform.validator.ts +77 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import type { VueformSchema, Vueform } from "@vueform/vueform";
|
|
2
|
+
|
|
3
|
+
interface FormSchemaMask {
|
|
4
|
+
mask: "number" | "string";
|
|
5
|
+
thousandsSeparator?: "," | "." | "";
|
|
6
|
+
radix?: "." | ",";
|
|
7
|
+
mapToRadix?: [".", ","] | [",", "."];
|
|
8
|
+
scale?: number;
|
|
9
|
+
min?: number;
|
|
10
|
+
max?: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface FormSchemaAddons {
|
|
14
|
+
before?: string;
|
|
15
|
+
after?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface FormSchemaColumns {
|
|
19
|
+
container: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface FormSchemaSubSelector {
|
|
23
|
+
label: string;
|
|
24
|
+
field: string;
|
|
25
|
+
fillFrom?: string;
|
|
26
|
+
fillFromFunc?: (item: any) => void;
|
|
27
|
+
submitField?: string;
|
|
28
|
+
autoSelect?: boolean;
|
|
29
|
+
selectedLabel?: string;
|
|
30
|
+
selectedLabelFunc?: (selected: any) => void;
|
|
31
|
+
selectedDesc?: string;
|
|
32
|
+
selectedDescFunc?: (selected: any) => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface FormSchemaHooks {
|
|
36
|
+
/**
|
|
37
|
+
* This will be called when form dialog/sheet open
|
|
38
|
+
* and display loading, the form are not rendered yet.
|
|
39
|
+
* Here you can change the schema to be rendered on form
|
|
40
|
+
*
|
|
41
|
+
* @param schema reactive form schema
|
|
42
|
+
* @param formType add / edit
|
|
43
|
+
* @param editData only available if edit
|
|
44
|
+
* @returns
|
|
45
|
+
* Promise, if return promise false will close the form
|
|
46
|
+
* if throw error, will display error dialog and close the form
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
onBeforeMount?: (schema: FormReactiveSchema, formType: "add" | "edit", editData?: any) => Promise<boolean>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* TODO:
|
|
53
|
+
* Please add descriptions about this hook
|
|
54
|
+
* @deprecated
|
|
55
|
+
* moved to page related hooks, now use pageDetailHooks on PageConfig
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
58
|
+
onMountedDetail?: (schema: DasiV2FormSchema, detailData?: any) => Promise<boolean>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* This will be called when the detail sheet are rendered,
|
|
62
|
+
* you can get the element via el$.el$ or change related schema
|
|
63
|
+
* via schema.value will change the rendered detail sheet
|
|
64
|
+
*
|
|
65
|
+
* @param schema reactive form schema, to change schema use schema.value[field_key],
|
|
66
|
+
* change the schema will change in the rendered the form
|
|
67
|
+
*
|
|
68
|
+
* @param formType add / edit
|
|
69
|
+
* @param editData only available if edit
|
|
70
|
+
* @returns
|
|
71
|
+
* Promise, if return promise false will close the form
|
|
72
|
+
* if throw error, will display error dialog and close the form
|
|
73
|
+
*
|
|
74
|
+
*/
|
|
75
|
+
onMounted?: (el$: FormEl, schema: FormReactiveSchema | any, formType: "add" | "edit", editData?: any) => Promise<boolean>;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* This will be called when use click submit before the form submited to api
|
|
79
|
+
* you change data to be submited to API on form$.data
|
|
80
|
+
*
|
|
81
|
+
* @param form$ you change what data to be submited to API by changing variable in form$.data
|
|
82
|
+
* the $form.data is the data form schema
|
|
83
|
+
* @returns
|
|
84
|
+
* Promise, if return promise false will prevent form from submiting
|
|
85
|
+
* if throw error, will display form error
|
|
86
|
+
*
|
|
87
|
+
*/
|
|
88
|
+
onBeforeSubmit?: (form$: FormFromSubmit) => Promise<boolean>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* This will be called when any of the field in the form was changed
|
|
92
|
+
*
|
|
93
|
+
* @param after object form$.data
|
|
94
|
+
* @param before object form$.data
|
|
95
|
+
* @param el$ form element, to get field element you can use el$.el$([field_key])
|
|
96
|
+
* @param schema reactive form schema, to change schema use schema.value[field_key],
|
|
97
|
+
* change the schema will change in the rendered the form
|
|
98
|
+
* @param formType add / edit
|
|
99
|
+
* @returns void
|
|
100
|
+
*
|
|
101
|
+
*/
|
|
102
|
+
onChange?: (after: any, before: any, el$: Vueform, schema: FormReactiveSchema | any, formType: "add" | "edit") => void;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface FormReactiveSchema {
|
|
106
|
+
value: DasiV2FormSchema;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface FormEl {
|
|
110
|
+
el$: any;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface FormReactiveSchema {
|
|
114
|
+
value: DasiV2FormSchema;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface FormFromSubmit {
|
|
118
|
+
data: any;
|
|
119
|
+
schema: any;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export type DasiV2FormSchema = Record<string, FormSchemaItem>;
|
|
123
|
+
|
|
124
|
+
export type FormSchema = {
|
|
125
|
+
schema: DasiV2FormSchema;
|
|
126
|
+
hooks?: FormSchemaHooks;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export interface FormSchemaItemItem {
|
|
130
|
+
value: any;
|
|
131
|
+
label: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface FormSchemaItemList {
|
|
135
|
+
element: FormSchema;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface FormSchemaItemListControls {
|
|
139
|
+
add?: boolean;
|
|
140
|
+
remove?: boolean;
|
|
141
|
+
sort?: boolean;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface FormSchemaItem {
|
|
145
|
+
key?: string;
|
|
146
|
+
type: "text" | "list" | "selector" | "static" | "date_selector" | "config_data_selector" | string;
|
|
147
|
+
cellType?: string;
|
|
148
|
+
label?: string;
|
|
149
|
+
title?: string,
|
|
150
|
+
cellHeader?: string;
|
|
151
|
+
text?: string;
|
|
152
|
+
inputType?: "text" | "number" | string;
|
|
153
|
+
addText?: string;
|
|
154
|
+
placeholder?: string;
|
|
155
|
+
rows?: number;
|
|
156
|
+
isEmpty?: any;
|
|
157
|
+
mask?: FormSchemaMask;
|
|
158
|
+
columns?: FormSchemaColumns | number;
|
|
159
|
+
rules?: string[];
|
|
160
|
+
addons?: FormSchemaAddons;
|
|
161
|
+
subItem?: FormSchemaSubSelector;
|
|
162
|
+
endpoint?: string;
|
|
163
|
+
nameField?: string;
|
|
164
|
+
nameFieldFunc?: (row: any) => string;
|
|
165
|
+
cellDescripton?: (i: number, item: any) => string | string;
|
|
166
|
+
cellDataSource?: (i: number, item: any) => any;
|
|
167
|
+
field?: string;
|
|
168
|
+
align?: string;
|
|
169
|
+
descriptionField?: string | ((row: any) => string);
|
|
170
|
+
descriptionFieldFunc?: (row: any) => string;
|
|
171
|
+
items?: FormSchemaItemItem[];
|
|
172
|
+
disabled?: boolean | any;
|
|
173
|
+
disableAutoLoad?: boolean;
|
|
174
|
+
sortKey?: string | string[];
|
|
175
|
+
showField?: boolean;
|
|
176
|
+
showInDetail?: boolean;
|
|
177
|
+
showInTable?: boolean;
|
|
178
|
+
cellRender?: (i: number, row: any) => string | null | undefined;
|
|
179
|
+
forceNumbers?: boolean;
|
|
180
|
+
description?: string;
|
|
181
|
+
drop?: boolean;
|
|
182
|
+
accept?: string;
|
|
183
|
+
schema?: DasiV2FormSchema;
|
|
184
|
+
messages?: any;
|
|
185
|
+
maxDate?: Date;
|
|
186
|
+
minDate?: Date;
|
|
187
|
+
buttonLabel?: string;
|
|
188
|
+
default?: any;
|
|
189
|
+
nullValue?: any;
|
|
190
|
+
parentCode?: string;
|
|
191
|
+
element?: any;
|
|
192
|
+
id?: string;
|
|
193
|
+
textAlign?: "right" | "center" | "right";
|
|
194
|
+
headAlign?: "right" | "center" | "left";
|
|
195
|
+
autofill?: boolean;
|
|
196
|
+
disabledValue?: boolean;
|
|
197
|
+
forceNumber?: boolean;
|
|
198
|
+
onKeyup?: (e: any) => void;
|
|
199
|
+
attrs?: any;
|
|
200
|
+
allowIncomplete?: boolean;
|
|
201
|
+
unmask?: boolean;
|
|
202
|
+
native?: boolean;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Can be class string or object
|
|
206
|
+
* please refer to https://vueform.com/recipes/add-custom-css-class-to-an-element
|
|
207
|
+
*
|
|
208
|
+
*/
|
|
209
|
+
addClass?: any;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* List
|
|
213
|
+
*
|
|
214
|
+
*/
|
|
215
|
+
controls?: FormSchemaItemListControls;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Static content
|
|
219
|
+
*
|
|
220
|
+
*/
|
|
221
|
+
content?: string;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Organization
|
|
225
|
+
*
|
|
226
|
+
*/
|
|
227
|
+
accessLevel?: string;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* For selector multiple
|
|
231
|
+
*
|
|
232
|
+
* if in dasi_v2_organizations default to organization
|
|
233
|
+
*
|
|
234
|
+
*/
|
|
235
|
+
objectKey?: string;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Organization selector
|
|
239
|
+
*
|
|
240
|
+
*/
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Dialog selector
|
|
244
|
+
*
|
|
245
|
+
*/
|
|
246
|
+
searchColumns?: string;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Dynamic Parameters for selectors
|
|
250
|
+
* Static query parameters to append to endpoint
|
|
251
|
+
*/
|
|
252
|
+
params?: Record<string, any>;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Condition parameters for selectors
|
|
256
|
+
* Formatted as key:value,key2:value2 in query string
|
|
257
|
+
*/
|
|
258
|
+
condition?: Record<string, any>;
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Order by field for selectors
|
|
262
|
+
*/
|
|
263
|
+
orderBy?: string;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Sort direction for selectors
|
|
267
|
+
*/
|
|
268
|
+
sort?: "asc" | "desc";
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Show avatar in selector
|
|
272
|
+
*/
|
|
273
|
+
showAvatar?: boolean;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Return full object instead of just ID
|
|
277
|
+
*/
|
|
278
|
+
returnObject?: boolean;
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Auto-fill with user organization
|
|
282
|
+
*/
|
|
283
|
+
autoFillOrg?: boolean;
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Enable multiple selection mode
|
|
287
|
+
*/
|
|
288
|
+
multiple?: boolean;
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Date picker type
|
|
292
|
+
* - date: Single date picker
|
|
293
|
+
* - datetime: Date and time picker
|
|
294
|
+
* - month: Month picker
|
|
295
|
+
* - year: Year picker
|
|
296
|
+
*/
|
|
297
|
+
pickerType?: "date" | "datetime" | "month" | "year";
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Enable range selection for date pickers
|
|
301
|
+
*/
|
|
302
|
+
range?: boolean;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Enable time picker for date pickers
|
|
306
|
+
*/
|
|
307
|
+
enableTimePicker?: boolean;
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Show time picker inline
|
|
311
|
+
*/
|
|
312
|
+
timePickerInline?: boolean;
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Custom display format for date values
|
|
316
|
+
*/
|
|
317
|
+
displayFormat?: string;
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Year range for date pickers [min, max]
|
|
321
|
+
*/
|
|
322
|
+
yearRange?: [number, number];
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Locale for date picker
|
|
326
|
+
*/
|
|
327
|
+
locale?: string;
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Auto apply date selection
|
|
331
|
+
*/
|
|
332
|
+
autoApply?: boolean;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Enable text input for date picker
|
|
336
|
+
*/
|
|
337
|
+
textInput?: boolean;
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Start date for range pickers
|
|
341
|
+
*/
|
|
342
|
+
startDate?: Date;
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Special prop for stock real functionality
|
|
346
|
+
*/
|
|
347
|
+
isStokReal?: boolean;
|
|
348
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Utilities
|
|
3
|
+
* Helper functions for safely accessing configuration values
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useAppConfig } from '@/composables/useAppConfig'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Get configuration value with fallback
|
|
10
|
+
* @param key - Configuration key path (e.g., 'auth.tokenKey')
|
|
11
|
+
* @param fallback - Fallback value if key not found
|
|
12
|
+
* @returns Configuration value or fallback
|
|
13
|
+
*/
|
|
14
|
+
export const getConfigValue = (key: string, fallback: any) => {
|
|
15
|
+
try {
|
|
16
|
+
const { getConfigValue: getValue } = useAppConfig()
|
|
17
|
+
return getValue(key) || fallback
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.warn('Failed to get config value:', error);
|
|
20
|
+
return fallback;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Default configuration values
|
|
26
|
+
*/
|
|
27
|
+
export const defaultConfigValues = {
|
|
28
|
+
auth: {
|
|
29
|
+
tokenKey: 'app.user.token',
|
|
30
|
+
userKey: 'app.user.name',
|
|
31
|
+
organizationKey: 'app.user.organization'
|
|
32
|
+
},
|
|
33
|
+
api: {
|
|
34
|
+
baseUrl: import.meta.env.VITE_API_URL || 'http://localhost:3000/api',
|
|
35
|
+
timeout: 30000,
|
|
36
|
+
endpoints: {
|
|
37
|
+
auth: {
|
|
38
|
+
login: '/auth/login',
|
|
39
|
+
logout: '/auth/logout',
|
|
40
|
+
refresh: '/user/refresh-token',
|
|
41
|
+
forgotPassword: '/auth/forgotpassword',
|
|
42
|
+
changePassword: '/auth/changepassword',
|
|
43
|
+
info: '/auth/info',
|
|
44
|
+
status: '/auth/status',
|
|
45
|
+
init: '/auth/login/init',
|
|
46
|
+
captcha: '/auth/captcha/init'
|
|
47
|
+
},
|
|
48
|
+
notifications: {
|
|
49
|
+
unreadCount: '/notif/unreadCount',
|
|
50
|
+
list: '/notif/list'
|
|
51
|
+
},
|
|
52
|
+
media: {
|
|
53
|
+
upload: '/media',
|
|
54
|
+
delete: '/media'
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
branding: {
|
|
59
|
+
companyName: 'Your Company',
|
|
60
|
+
logo: '/img/brand/logo.svg',
|
|
61
|
+
primaryColor: '#3B82F6'
|
|
62
|
+
},
|
|
63
|
+
organization: {
|
|
64
|
+
defaultLevel: 'user'
|
|
65
|
+
},
|
|
66
|
+
features: {
|
|
67
|
+
realTimeNotifications: false
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get auth configuration values
|
|
73
|
+
*/
|
|
74
|
+
export const getAuthConfig = () => {
|
|
75
|
+
try {
|
|
76
|
+
const { authConfig } = useAppConfig()
|
|
77
|
+
return {
|
|
78
|
+
tokenKey: authConfig.value.tokenKey,
|
|
79
|
+
userKey: authConfig.value.userKey,
|
|
80
|
+
organizationKey: authConfig.value.organizationKey
|
|
81
|
+
}
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.warn('Failed to get auth config:', error);
|
|
84
|
+
return defaultConfigValues.auth;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get API configuration values
|
|
90
|
+
*/
|
|
91
|
+
export const getApiConfig = () => {
|
|
92
|
+
try {
|
|
93
|
+
const { apiBaseUrl, apiEndpoints } = useAppConfig()
|
|
94
|
+
return {
|
|
95
|
+
baseUrl: apiBaseUrl.value,
|
|
96
|
+
timeout: 30000,
|
|
97
|
+
endpoints: apiEndpoints.value
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.warn('Failed to get API config:', error);
|
|
101
|
+
return defaultConfigValues.api;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Get branding configuration values
|
|
107
|
+
*/
|
|
108
|
+
export const getBrandingConfig = () => {
|
|
109
|
+
try {
|
|
110
|
+
const { companyName, logo, primaryColor } = useAppConfig()
|
|
111
|
+
return {
|
|
112
|
+
companyName: companyName.value,
|
|
113
|
+
logo: logo.value,
|
|
114
|
+
primaryColor: primaryColor.value
|
|
115
|
+
}
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.warn('Failed to get branding config:', error);
|
|
118
|
+
return defaultConfigValues.branding;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get organization configuration values
|
|
124
|
+
*/
|
|
125
|
+
export const getOrganizationConfig = () => {
|
|
126
|
+
try {
|
|
127
|
+
const { organizationLevels, defaultOrgLevel } = useAppConfig()
|
|
128
|
+
return {
|
|
129
|
+
levels: organizationLevels.value,
|
|
130
|
+
defaultLevel: defaultOrgLevel.value
|
|
131
|
+
}
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.warn('Failed to get organization config:', error);
|
|
134
|
+
return defaultConfigValues.organization;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get features configuration values
|
|
140
|
+
*/
|
|
141
|
+
export const getFeaturesConfig = () => {
|
|
142
|
+
try {
|
|
143
|
+
const { enabledFeatures } = useAppConfig()
|
|
144
|
+
return enabledFeatures.value
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.warn('Failed to get features config:', error);
|
|
147
|
+
return defaultConfigValues.features;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import BtnPrimary from '@/components/button/BtnPrimary.vue';
|
|
3
|
+
import { LucideOctagonAlert } from 'lucide-vue-next';
|
|
4
|
+
|
|
5
|
+
function backToHome() {
|
|
6
|
+
const defaultApp = localStorage.getItem('app.user.default_app');
|
|
7
|
+
const nextUri = defaultApp === 'app1' ? '/dashboard' : '/';
|
|
8
|
+
window.location.href = nextUri;
|
|
9
|
+
}
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<section class="h-screen flex items-center justify-center bg-red-100">
|
|
14
|
+
<div class="text-center text-red-500 w-full max-w-[520px] px-5">
|
|
15
|
+
<LucideOctagonAlert class="mx-auto mb-5" :size="46" :stroke-width="1.3"/>
|
|
16
|
+
<h4 class="font-semibold text-lg mb-1">
|
|
17
|
+
Halaman Tidak Ditemukan
|
|
18
|
+
</h4>
|
|
19
|
+
<p class="text-sm mb-4">
|
|
20
|
+
Maaf, halaman tidak tersedia, mungkin anda klik link yang salah atau
|
|
21
|
+
halaman yang Anda cari tidak tersedia atau telah dihapus.<br />
|
|
22
|
+
Mohon periksa kembali url yang Anda masukkan.
|
|
23
|
+
</p>
|
|
24
|
+
<BtnPrimary class="rounded-full py-0 h-9"
|
|
25
|
+
v-on:click="backToHome">
|
|
26
|
+
Kembali Ke Halaman Depan
|
|
27
|
+
</BtnPrimary>
|
|
28
|
+
</div>
|
|
29
|
+
</section>
|
|
30
|
+
</template>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import PageActivity from "@/components/pages/PageActivity.vue";
|
|
3
|
+
import { ref } from "vue";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Mode binding
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
const pageCode = ref<string>('');
|
|
10
|
+
const endpoint = ref<string>('');
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<PageActivity v-model:endpoint="endpoint" v-model:page-code="pageCode"/>
|
|
15
|
+
</template>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import api from '@/api/api';
|
|
3
|
+
import BtnSecondary from '@/components/button/BtnSecondary.vue';
|
|
4
|
+
import LoadingIndicator from '@/components/loadings/LoadingIndicator.vue';
|
|
5
|
+
import { onMounted, ref } from 'vue';
|
|
6
|
+
import { useRoute } from 'vue-router';
|
|
7
|
+
import { nanoid, customAlphabet } from 'nanoid';
|
|
8
|
+
|
|
9
|
+
const route = useRoute();
|
|
10
|
+
const authError = ref<string | null>(null);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* NanoId custom for nonce sso
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
const nanoIdCustom = customAlphabet('1234567890', 6)
|
|
17
|
+
|
|
18
|
+
function tryAgain() {
|
|
19
|
+
/**
|
|
20
|
+
* Used to prevent CSRF attacks by
|
|
21
|
+
* ensuring the response matches the initial request
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
const state = nanoid(12);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Used to prevent replay attacks by
|
|
28
|
+
* ensuring the authentication response is unique and fresh.
|
|
29
|
+
*
|
|
30
|
+
*/
|
|
31
|
+
const nonce = nanoIdCustom(6);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Save one-time only state
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
sessionStorage.setItem('oauth_state', state);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Redirect to oauth login
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
43
|
+
window.location.href = `${import.meta.env.VITE_AUTH_AUTHORIZE_URL}?`
|
|
44
|
+
+ `client_id=${import.meta.env.VITE_AUTH_CLIENT_ID}&`
|
|
45
|
+
+ `redirect_uri=${import.meta.env.VITE_AUTH_REDIRECT_URL}&`
|
|
46
|
+
+ `response_type=code&state=${state}&nonce=${nonce}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function isValidPath(uri: any) {
|
|
50
|
+
// Check if the URI is a relative path within your site
|
|
51
|
+
return typeof uri === "string" && uri.startsWith("/") && !uri.startsWith("//") && uri.length > 1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
onMounted(() => {
|
|
55
|
+
const { code, state } = route.query;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Validate nonce and state
|
|
59
|
+
*
|
|
60
|
+
*/
|
|
61
|
+
const storedState = sessionStorage.getItem('oauth_state');
|
|
62
|
+
if (storedState !== state) {
|
|
63
|
+
authError.value = 'State failed, please try again.';
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Exchange token
|
|
69
|
+
*
|
|
70
|
+
*/
|
|
71
|
+
api.post('/auth/exchange', { code }).then((r) => {
|
|
72
|
+
// Note: These localStorage keys should ideally come from config
|
|
73
|
+
// For now, using generic keys that can be configured
|
|
74
|
+
if (r.data.auth_token) localStorage.setItem('app.user.token', r.data.auth_token);
|
|
75
|
+
localStorage.setItem('app.user.name', r.data.user.name);
|
|
76
|
+
localStorage.setItem('app.user.default_app', r.data.user.defaultApp);
|
|
77
|
+
if (r.data.user.organization) localStorage.setItem('app.user.organization', r.data.user.organization.name);
|
|
78
|
+
const nextUri = r.data.user.defaultApp === 'app1' ? '/dashboard/profile-sentral' : '/apk2/overview';
|
|
79
|
+
let nextUriFromSession = sessionStorage.getItem('dasi.next');
|
|
80
|
+
window.location.href = nextUriFromSession && isValidPath(nextUriFromSession) ? nextUriFromSession : nextUri;
|
|
81
|
+
}).catch((err) => {
|
|
82
|
+
console.error(err);
|
|
83
|
+
authError.value = 'Session expired, please try again';
|
|
84
|
+
});
|
|
85
|
+
})
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
<template>
|
|
89
|
+
<section>
|
|
90
|
+
<div class="flex flex-col items-center justify-center space-y-2" v-if="authError">
|
|
91
|
+
<h1 class="text-2xl font-semibold tracking-tight text-red-500">
|
|
92
|
+
Login Gagal
|
|
93
|
+
</h1>
|
|
94
|
+
<p class="text-sm text-muted-foreground text-red-500">
|
|
95
|
+
{{ authError }}
|
|
96
|
+
</p>
|
|
97
|
+
<BtnSecondary v-on:click="tryAgain">Coba Lagi</BtnSecondary>
|
|
98
|
+
</div>
|
|
99
|
+
<LoadingIndicator class="mx-auto scale-90" v-else/>
|
|
100
|
+
</section>
|
|
101
|
+
</template>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
</script>
|
|
3
|
+
|
|
4
|
+
<template>
|
|
5
|
+
<div class="flex flex-col w-full">
|
|
6
|
+
<!-- header -->
|
|
7
|
+
<!-- <div class="flex flex-row items-center w-full bg-[#fff] dark:bg-black dark:border-b dark:border-b-gray-900">
|
|
8
|
+
<h1 class="text-2xl font-semibold text-[#4D5E80] dark:text-slate-200 px-[24px] py-[16px]">Dashboard</h1>
|
|
9
|
+
</div> -->
|
|
10
|
+
<!-- main content -->
|
|
11
|
+
<div className="p-5 pb-0">
|
|
12
|
+
<div className="grid grid-cols-12 gap-5 min-h-[calc(100vh-110px)] 2xl:min-h-[calc(100vh-136px)]">
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|