.
This commit is contained in:
parent
7f363cd64a
commit
1caa778374
@ -1,35 +1,4 @@
|
|||||||
import {
|
|
||||||
Badge,
|
|
||||||
Button,
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardDescription,
|
|
||||||
CardFooter,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuCheckboxItem,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuLabel,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
Tabs,
|
|
||||||
TabsContent,
|
|
||||||
TabsList,
|
|
||||||
TabsTrigger,
|
|
||||||
} from "@/ui";
|
|
||||||
|
|
||||||
import { File, ListFilter, MoreHorizontal, PlusCircle } from "lucide-react";
|
|
||||||
|
|
||||||
import { DataTableProvider } from "@/lib/hooks";
|
import { DataTableProvider } from "@/lib/hooks";
|
||||||
import { Trans } from "react-i18next";
|
|
||||||
import { CatalogDataTable } from "./components";
|
import { CatalogDataTable } from "./components";
|
||||||
|
|
||||||
export const CatalogList = () => {
|
export const CatalogList = () => {
|
||||||
@ -38,282 +7,4 @@ export const CatalogList = () => {
|
|||||||
<CatalogDataTable />
|
<CatalogDataTable />
|
||||||
</DataTableProvider>
|
</DataTableProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Tabs defaultValue='all'>
|
|
||||||
<div className='flex items-center'>
|
|
||||||
<TabsList>
|
|
||||||
<TabsTrigger value='all'>All</TabsTrigger>
|
|
||||||
<TabsTrigger value='active'>Active</TabsTrigger>
|
|
||||||
<TabsTrigger value='draft'>Draft</TabsTrigger>
|
|
||||||
<TabsTrigger value='archived' className='hidden sm:flex'>
|
|
||||||
Archived
|
|
||||||
</TabsTrigger>
|
|
||||||
</TabsList>
|
|
||||||
<div className='flex items-center gap-2 ml-auto'>
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant='outline' size='sm' className='h-8 gap-1'>
|
|
||||||
<ListFilter className='h-3.5 w-3.5' />
|
|
||||||
<span className='sr-only sm:not-sr-only sm:whitespace-nowrap'>Filter</span>
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align='end'>
|
|
||||||
<DropdownMenuLabel>Filter by</DropdownMenuLabel>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuCheckboxItem checked>Active</DropdownMenuCheckboxItem>
|
|
||||||
<DropdownMenuCheckboxItem>Draft</DropdownMenuCheckboxItem>
|
|
||||||
<DropdownMenuCheckboxItem>Archived</DropdownMenuCheckboxItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
<Button size='sm' variant='outline' className='h-8 gap-1'>
|
|
||||||
<File className='h-3.5 w-3.5' />
|
|
||||||
<span className='sr-only sm:not-sr-only sm:whitespace-nowrap'>Export</span>
|
|
||||||
</Button>
|
|
||||||
<Button size='sm' className='h-8 gap-1'>
|
|
||||||
<PlusCircle className='h-3.5 w-3.5' />
|
|
||||||
<span className='sr-only sm:not-sr-only sm:whitespace-nowrap'>Add Product</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<TabsContent value='all'>
|
|
||||||
<Card x-chunk='dashboard-06-chunk-0'>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>
|
|
||||||
<Trans i18nKey='catalog.title' />
|
|
||||||
</CardTitle>
|
|
||||||
<CardDescription>
|
|
||||||
Manage your products and view their sales performance.
|
|
||||||
</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<Table>
|
|
||||||
<TableHeader>
|
|
||||||
<TableRow>
|
|
||||||
<TableHead className='hidden w-[100px] sm:table-cell'>
|
|
||||||
<span className='sr-only'>Image</span>
|
|
||||||
</TableHead>
|
|
||||||
<TableHead>Name</TableHead>
|
|
||||||
<TableHead>Status</TableHead>
|
|
||||||
<TableHead className='hidden md:table-cell'>Price</TableHead>
|
|
||||||
<TableHead className='hidden md:table-cell'>Total Sales</TableHead>
|
|
||||||
<TableHead className='hidden md:table-cell'>Created at</TableHead>
|
|
||||||
<TableHead>
|
|
||||||
<span className='sr-only'>Actions</span>
|
|
||||||
</TableHead>
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell className='hidden sm:table-cell'>
|
|
||||||
<img
|
|
||||||
alt='Product image'
|
|
||||||
className='object-cover rounded-md aspect-square'
|
|
||||||
height='64'
|
|
||||||
src='/placeholder.svg'
|
|
||||||
width='64'
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='font-medium'>Laser Lemonade Machine</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<Badge variant='outline'>Draft</Badge>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>$499.99</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>25</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>2023-07-12 10:42 AM</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button aria-haspopup='true' size='icon' variant='ghost'>
|
|
||||||
<MoreHorizontal className='w-4 h-4' />
|
|
||||||
<span className='sr-only'>Toggle menu</span>
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align='end'>
|
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
||||||
<DropdownMenuItem>Edit</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>Delete</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell className='hidden sm:table-cell'>
|
|
||||||
<img
|
|
||||||
alt='Product image'
|
|
||||||
className='object-cover rounded-md aspect-square'
|
|
||||||
height='64'
|
|
||||||
src='/placeholder.svg'
|
|
||||||
width='64'
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='font-medium'>Hypernova Headphones</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<Badge variant='outline'>Active</Badge>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>$129.99</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>100</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>2023-10-18 03:21 PM</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button aria-haspopup='true' size='icon' variant='ghost'>
|
|
||||||
<MoreHorizontal className='w-4 h-4' />
|
|
||||||
<span className='sr-only'>Toggle menu</span>
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align='end'>
|
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
||||||
<DropdownMenuItem>Edit</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>Delete</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell className='hidden sm:table-cell'>
|
|
||||||
<img
|
|
||||||
alt='Product image'
|
|
||||||
className='object-cover rounded-md aspect-square'
|
|
||||||
height='64'
|
|
||||||
src='/placeholder.svg'
|
|
||||||
width='64'
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='font-medium'>AeroGlow Desk Lamp</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<Badge variant='outline'>Active</Badge>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>$39.99</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>50</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>2023-11-29 08:15 AM</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button aria-haspopup='true' size='icon' variant='ghost'>
|
|
||||||
<MoreHorizontal className='w-4 h-4' />
|
|
||||||
<span className='sr-only'>Toggle menu</span>
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align='end'>
|
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
||||||
<DropdownMenuItem>Edit</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>Delete</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell className='hidden sm:table-cell'>
|
|
||||||
<img
|
|
||||||
alt='Product image'
|
|
||||||
className='object-cover rounded-md aspect-square'
|
|
||||||
height='64'
|
|
||||||
src='/placeholder.svg'
|
|
||||||
width='64'
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='font-medium'>TechTonic Energy Drink</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<Badge variant='secondary'>Draft</Badge>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>$2.99</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>0</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>2023-12-25 11:59 PM</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button aria-haspopup='true' size='icon' variant='ghost'>
|
|
||||||
<MoreHorizontal className='w-4 h-4' />
|
|
||||||
<span className='sr-only'>Toggle menu</span>
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align='end'>
|
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
||||||
<DropdownMenuItem>Edit</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>Delete</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell className='hidden sm:table-cell'>
|
|
||||||
<img
|
|
||||||
alt='Product image'
|
|
||||||
className='object-cover rounded-md aspect-square'
|
|
||||||
height='64'
|
|
||||||
src='/placeholder.svg'
|
|
||||||
width='64'
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='font-medium'>Gamer Gear Pro Controller</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<Badge variant='outline'>Active</Badge>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>$59.99</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>75</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>2024-01-01 12:00 AM</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button aria-haspopup='true' size='icon' variant='ghost'>
|
|
||||||
<MoreHorizontal className='w-4 h-4' />
|
|
||||||
<span className='sr-only'>Toggle menu</span>
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align='end'>
|
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
||||||
<DropdownMenuItem>Edit</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>Delete</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell className='hidden sm:table-cell'>
|
|
||||||
<img
|
|
||||||
alt='Product image'
|
|
||||||
className='object-cover rounded-md aspect-square'
|
|
||||||
height='64'
|
|
||||||
src='/placeholder.svg'
|
|
||||||
width='64'
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='font-medium'>Luminous VR Headset</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<Badge variant='outline'>Active</Badge>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>$199.99</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>30</TableCell>
|
|
||||||
<TableCell className='hidden md:table-cell'>2024-02-14 02:14 PM</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button aria-haspopup='true' size='icon' variant='ghost'>
|
|
||||||
<MoreHorizontal className='w-4 h-4' />
|
|
||||||
<span className='sr-only'>Toggle menu</span>
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align='end'>
|
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
||||||
<DropdownMenuItem>Edit</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>Delete</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</CardContent>
|
|
||||||
<CardFooter>
|
|
||||||
<div className='text-xs text-muted-foreground'>
|
|
||||||
Showing <strong>1-10</strong> of <strong>32</strong> products
|
|
||||||
</div>
|
|
||||||
</CardFooter>
|
|
||||||
</Card>
|
|
||||||
</TabsContent>
|
|
||||||
</Tabs>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -33,21 +33,20 @@ type SettingsDataForm = {
|
|||||||
export const SettingsEditor = () => {
|
export const SettingsEditor = () => {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const {
|
const { useQuery, useMutation } = useSettings();
|
||||||
query: { data },
|
|
||||||
mutation: { mutate },
|
|
||||||
} = useSettings();
|
|
||||||
|
|
||||||
console.log(data);
|
const { data } = useQuery;
|
||||||
|
const { mutate } = useMutation;
|
||||||
|
|
||||||
const form = useForm<SettingsDataForm>({
|
const form = useForm<SettingsDataForm>({
|
||||||
mode: "onBlur",
|
mode: "onBlur",
|
||||||
|
values: data,
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
contact_information: data?.contact_information ?? "",
|
contact_information: "",
|
||||||
default_payment_method: data?.default_payment_method ?? "",
|
default_payment_method: "",
|
||||||
default_notes: data?.default_notes ?? "",
|
default_notes: "",
|
||||||
default_legal_terms: data?.default_legal_terms ?? "",
|
default_legal_terms: "",
|
||||||
default_quote_validity: data?.default_quote_validity ?? "",
|
default_quote_validity: "",
|
||||||
},
|
},
|
||||||
/*resolver: joiResolver(
|
/*resolver: joiResolver(
|
||||||
Joi.object({
|
Joi.object({
|
||||||
|
|||||||
@ -13,7 +13,7 @@ export const useSettings = (params?: UseSettingsGetParamsType) => {
|
|||||||
const keys = useQueryKey();
|
const keys = useQueryKey();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
query: useOne<IGetProfileResponse_DTO>({
|
useQuery: useOne<IGetProfileResponse_DTO>({
|
||||||
queryKey: keys().data().resource("settings").action("one").id("").params().get(),
|
queryKey: keys().data().resource("settings").action("one").id("").params().get(),
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
dataSource.getOne({
|
dataSource.getOne({
|
||||||
@ -22,7 +22,7 @@ export const useSettings = (params?: UseSettingsGetParamsType) => {
|
|||||||
}),
|
}),
|
||||||
...params,
|
...params,
|
||||||
}),
|
}),
|
||||||
mutation: useSave({
|
useMutation: useSave({
|
||||||
mutationKey: keys().data().resource("settings").action("one").id("").params().get(),
|
mutationKey: keys().data().resource("settings").action("one").id("").params().get(),
|
||||||
mutationFn: (data) =>
|
mutationFn: (data) =>
|
||||||
dataSource.updateOne({
|
dataSource.updateOne({
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useCustomDialog } from "@/lib/hooks";
|
import { useCustomDialog, useGetIdentity } from "@/lib/hooks";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
@ -32,7 +32,9 @@ export const UserButton = () => {
|
|||||||
navigate("/logout");
|
navigate("/logout");
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
//const { data, status } = useGetIdentity();
|
const { data, status } = useGetIdentity();
|
||||||
|
|
||||||
|
console.log(data, status);
|
||||||
|
|
||||||
const openUserMenu = (event: SyntheticEvent) => {
|
const openUserMenu = (event: SyntheticEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -51,10 +53,18 @@ export const UserButton = () => {
|
|||||||
return (
|
return (
|
||||||
<DropdownMenu open={userMenuOpened} onOpenChange={setUserMenuOpened}>
|
<DropdownMenu open={userMenuOpened} onOpenChange={setUserMenuOpened}>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button variant='secondary' size='icon' className='rounded-full' onClick={openUserMenu}>
|
<>
|
||||||
<CircleUserIcon className='w-5 h-5' />
|
{status === "success" && (
|
||||||
<span className='sr-only'>{t("main_menu.user.user_menu")}</span>
|
<div className='grid gap-1 text-right'>
|
||||||
</Button>
|
<p className='text-sm font-medium leading-none'>{data?.name}</p>
|
||||||
|
<p className='text-sm text-muted-foreground'>{data?.email}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<Button variant='secondary' size='icon' className='rounded-full' onClick={openUserMenu}>
|
||||||
|
<CircleUserIcon className='w-5 h-5' />
|
||||||
|
<span className='sr-only'>{t("main_menu.user.user_menu")}</span>
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align='end' className='w-56'>
|
<DropdownMenuContent align='end' className='w-56'>
|
||||||
<DropdownMenuLabel>{t("main_menu.user.my_account")}</DropdownMenuLabel>
|
<DropdownMenuLabel>{t("main_menu.user.my_account")}</DropdownMenuLabel>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useAuth } from "@/lib/hooks";
|
import { IdentityResponse, useAuth } from "@/lib/hooks";
|
||||||
import { UseQueryOptions, useQuery } from "@tanstack/react-query";
|
import { UseQueryOptions, useQuery } from "@tanstack/react-query";
|
||||||
import { useQueryKey } from "../useQueryKey";
|
import { useQueryKey } from "../useQueryKey";
|
||||||
|
|
||||||
@ -6,9 +6,11 @@ export const useGetIdentity = (queryOptions?: UseQueryOptions) => {
|
|||||||
const keys = useQueryKey();
|
const keys = useQueryKey();
|
||||||
const { getIdentity } = useAuth();
|
const { getIdentity } = useAuth();
|
||||||
|
|
||||||
return useQuery({
|
return useQuery<IdentityResponse, Error>({
|
||||||
queryKey: keys().auth().action("identity").get(),
|
queryKey: keys().auth().action("identity").get(),
|
||||||
queryFn: getIdentity,
|
queryFn: getIdentity,
|
||||||
...queryOptions,
|
...queryOptions,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isAdmin = () => true;
|
||||||
|
|||||||
@ -20,10 +20,7 @@ export interface ISequelizeQueryOptions extends IRepositoryQueryOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ISequelizeQueryBuilder extends IRepositoryQueryBuilder {
|
export interface ISequelizeQueryBuilder extends IRepositoryQueryBuilder {
|
||||||
generateQuery: (props: {
|
generateQuery: (props: { model: any; queryCriteria?: IQueryCriteria }) => ISequelizeQueryOptions;
|
||||||
model: any;
|
|
||||||
queryCriteria?: IQueryCriteria;
|
|
||||||
}) => ISequelizeQueryOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SequelizeQueryBuilder implements ISequelizeQueryBuilder {
|
export class SequelizeQueryBuilder implements ISequelizeQueryBuilder {
|
||||||
@ -44,15 +41,11 @@ export class SequelizeQueryBuilder implements ISequelizeQueryBuilder {
|
|||||||
|
|
||||||
private applyQuickSearch(
|
private applyQuickSearch(
|
||||||
model: ModelDefined<any, any>,
|
model: ModelDefined<any, any>,
|
||||||
quickSearchCriteria: QuickSearchCriteria,
|
quickSearchCriteria: QuickSearchCriteria
|
||||||
): any {
|
): any {
|
||||||
let _model = model;
|
let _model = model;
|
||||||
if (!quickSearchCriteria.isEmpty()) {
|
if (!quickSearchCriteria.isEmpty()) {
|
||||||
if (
|
if (_model && _model.options.scopes && _model.options.scopes["quickSearch"]) {
|
||||||
_model &&
|
|
||||||
_model.options.scopes &&
|
|
||||||
_model.options.scopes["quickSearch"]
|
|
||||||
) {
|
|
||||||
_model = _model.scope({
|
_model = _model.scope({
|
||||||
method: ["quickSearch", quickSearchCriteria.value],
|
method: ["quickSearch", quickSearchCriteria.value],
|
||||||
});
|
});
|
||||||
|
|||||||
@ -30,11 +30,11 @@ export default (sequelize: Sequelize) => {
|
|||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
contact_information: DataTypes.STRING,
|
contact_information: DataTypes.TEXT,
|
||||||
default_payment_method: DataTypes.STRING,
|
default_payment_method: DataTypes.TEXT,
|
||||||
default_notes: DataTypes.STRING,
|
default_notes: DataTypes.TEXT,
|
||||||
default_legal_terms: DataTypes.STRING,
|
default_legal_terms: DataTypes.TEXT,
|
||||||
default_quote_validity: DataTypes.STRING,
|
default_quote_validity: DataTypes.TEXT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sequelize,
|
sequelize,
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import {
|
|||||||
Result,
|
Result,
|
||||||
UniqueID,
|
UniqueID,
|
||||||
} from "@shared/contexts";
|
} from "@shared/contexts";
|
||||||
import { DealerRole } from "./DealerRole";
|
|
||||||
import { DealerStatus } from "./DealerStatus";
|
import { DealerStatus } from "./DealerStatus";
|
||||||
|
|
||||||
export interface IDealerProps {
|
export interface IDealerProps {
|
||||||
@ -15,7 +14,6 @@ export interface IDealerProps {
|
|||||||
name: Name;
|
name: Name;
|
||||||
logo: string;
|
logo: string;
|
||||||
language: Language;
|
language: Language;
|
||||||
roles: DealerRole[];
|
|
||||||
additionalInfo: KeyValueMap;
|
additionalInfo: KeyValueMap;
|
||||||
status: DealerStatus;
|
status: DealerStatus;
|
||||||
}
|
}
|
||||||
@ -28,7 +26,6 @@ export interface IDealer {
|
|||||||
|
|
||||||
additionalInfo: KeyValueMap;
|
additionalInfo: KeyValueMap;
|
||||||
status: DealerStatus;
|
status: DealerStatus;
|
||||||
getRoles: () => DealerRole[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Dealer extends AggregateRoot<IDealerProps> implements IDealer {
|
export class Dealer extends AggregateRoot<IDealerProps> implements IDealer {
|
||||||
@ -37,14 +34,6 @@ export class Dealer extends AggregateRoot<IDealerProps> implements IDealer {
|
|||||||
return Result.ok<Dealer>(user);
|
return Result.ok<Dealer>(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private roles: DealerRole[];
|
|
||||||
|
|
||||||
constructor(props: IDealerProps, id?: UniqueID) {
|
|
||||||
const { roles } = props;
|
|
||||||
super(props, id);
|
|
||||||
this.roles = roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
get user_id(): UniqueID {
|
get user_id(): UniqueID {
|
||||||
return this.props.user_id;
|
return this.props.user_id;
|
||||||
}
|
}
|
||||||
@ -64,20 +53,4 @@ export class Dealer extends AggregateRoot<IDealerProps> implements IDealer {
|
|||||||
get additionalInfo(): KeyValueMap {
|
get additionalInfo(): KeyValueMap {
|
||||||
return this.props.additionalInfo;
|
return this.props.additionalInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isUser(): boolean {
|
|
||||||
return this._hasRole(DealerRole.ROLE_USER);
|
|
||||||
}
|
|
||||||
|
|
||||||
get isAdmin(): boolean {
|
|
||||||
return this._hasRole(DealerRole.ROLE_ADMIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getRoles(): DealerRole[] {
|
|
||||||
return this.roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _hasRole(role: DealerRole): boolean {
|
|
||||||
return (this.roles || []).some((r) => r.equals(role));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,13 +63,9 @@ export class DealerRepository extends SequelizeRepository<Dealer> implements IDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async findAll(queryCriteria?: IQueryCriteria): Promise<ICollection<any>> {
|
public async findAll(queryCriteria?: IQueryCriteria): Promise<ICollection<any>> {
|
||||||
const { rows, count } = await this._findAll(
|
const { rows, count } = await this._findAll("Dealer_Model", queryCriteria, {
|
||||||
"Dealer_Model",
|
include: [], // esto es para quitar las asociaciones al hacer la consulta
|
||||||
queryCriteria
|
});
|
||||||
/*{
|
|
||||||
include: [], // esto es para quitar las asociaciones al hacer la consulta
|
|
||||||
}*/
|
|
||||||
);
|
|
||||||
|
|
||||||
return this.mapper.mapArrayAndCountToDomain(rows, count);
|
return this.mapper.mapArrayAndCountToDomain(rows, count);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import {
|
|||||||
} from "@/contexts/common/infrastructure";
|
} from "@/contexts/common/infrastructure";
|
||||||
import { KeyValueMap, Language, Name, UniqueID } from "@shared/contexts";
|
import { KeyValueMap, Language, Name, UniqueID } from "@shared/contexts";
|
||||||
import { Dealer, DealerStatus, IDealerProps } from "../../domain/entities";
|
import { Dealer, DealerStatus, IDealerProps } from "../../domain/entities";
|
||||||
import { DealerRole } from "../../domain/entities/DealerRole";
|
|
||||||
import { ISalesContext } from "../Sales.context";
|
import { ISalesContext } from "../Sales.context";
|
||||||
import { DealerCreationAttributes, Dealer_Model } from "../sequelize";
|
import { DealerCreationAttributes, Dealer_Model } from "../sequelize";
|
||||||
|
|
||||||
@ -26,7 +25,6 @@ class DealerMapper
|
|||||||
logo: "",
|
logo: "",
|
||||||
name: this.mapsValue(source, "name", Name.create),
|
name: this.mapsValue(source, "name", Name.create),
|
||||||
status: this.mapsValue(source, "status", DealerStatus.create),
|
status: this.mapsValue(source, "status", DealerStatus.create),
|
||||||
roles: this.mapsValue(source, "roles", DealerRole.create),
|
|
||||||
language: this.mapsValue(source, "language", Language.createFromCode),
|
language: this.mapsValue(source, "language", Language.createFromCode),
|
||||||
additionalInfo: KeyValueMap.create([
|
additionalInfo: KeyValueMap.create([
|
||||||
["contact_information", source.contact_information],
|
["contact_information", source.contact_information],
|
||||||
|
|||||||
@ -74,11 +74,11 @@ export default (sequelize: Sequelize) => {
|
|||||||
allowNull: false,
|
allowNull: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
contact_information: DataTypes.STRING,
|
contact_information: DataTypes.TEXT,
|
||||||
default_payment_method: DataTypes.STRING,
|
default_payment_method: DataTypes.TEXT,
|
||||||
default_notes: DataTypes.STRING,
|
default_notes: DataTypes.TEXT,
|
||||||
default_legal_terms: DataTypes.STRING,
|
default_legal_terms: DataTypes.TEXT,
|
||||||
default_quote_validity: DataTypes.STRING,
|
default_quote_validity: DataTypes.TEXT,
|
||||||
language: DataTypes.STRING,
|
language: DataTypes.STRING,
|
||||||
|
|
||||||
status: {
|
status: {
|
||||||
@ -104,6 +104,13 @@ export default (sequelize: Sequelize) => {
|
|||||||
],
|
],
|
||||||
|
|
||||||
whereMergeStrategy: "and", // <- cómo tratar el merge de un scope
|
whereMergeStrategy: "and", // <- cómo tratar el merge de un scope
|
||||||
|
|
||||||
|
defaultScope: {
|
||||||
|
attributes: {
|
||||||
|
exclude: ["contact_id"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
scopes: {
|
scopes: {
|
||||||
quickSearch(value) {
|
quickSearch(value) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -7,13 +7,17 @@ import {
|
|||||||
NonAttribute,
|
NonAttribute,
|
||||||
Sequelize,
|
Sequelize,
|
||||||
} from "sequelize";
|
} from "sequelize";
|
||||||
|
import { Dealer_Model } from "./dealer.model";
|
||||||
import { QuoteItem_Model } from "./quoteItem.model";
|
import { QuoteItem_Model } from "./quoteItem.model";
|
||||||
|
|
||||||
export type QuoteCreationAttributes = InferCreationAttributes<Quote_Model, { omit: "items" }>;
|
export type QuoteCreationAttributes = InferCreationAttributes<
|
||||||
|
Quote_Model,
|
||||||
|
{ omit: "items" | "dealer" }
|
||||||
|
>;
|
||||||
|
|
||||||
export class Quote_Model extends Model<
|
export class Quote_Model extends Model<
|
||||||
InferAttributes<Quote_Model, { omit: "items" }>,
|
InferAttributes<Quote_Model, { omit: "items" | "dealer" }>,
|
||||||
InferCreationAttributes<Quote_Model, { omit: "items" }>
|
InferCreationAttributes<Quote_Model, { omit: "items" | "dealer" }>
|
||||||
> {
|
> {
|
||||||
static associate(connection: Sequelize) {
|
static associate(connection: Sequelize) {
|
||||||
const { Quote_Model, QuoteItem_Model, Dealer_Model } = connection.models;
|
const { Quote_Model, QuoteItem_Model, Dealer_Model } = connection.models;
|
||||||
@ -39,7 +43,8 @@ export class Quote_Model extends Model<
|
|||||||
declare subtotal: number;
|
declare subtotal: number;
|
||||||
declare total: number;
|
declare total: number;
|
||||||
|
|
||||||
declare items: NonAttribute<QuoteItem_Model[]>;
|
declare items?: NonAttribute<QuoteItem_Model[]>;
|
||||||
|
declare dealer?: NonAttribute<Dealer_Model>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (sequelize: Sequelize) => {
|
export default (sequelize: Sequelize) => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user