diff --git a/dashboard/package.json b/dashboard/package.json index 95caefd..f13ab00 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -99,6 +99,7 @@ "sonner": "^1.4.41", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", + "use-debounce": "^10.0.3", "vaul": "^0.9.1", "yaml": "^2.5.0", "zod": "^3.23.8", diff --git a/dashboard/pnpm-lock.yaml b/dashboard/pnpm-lock.yaml index 0244734..73a8fd6 100644 --- a/dashboard/pnpm-lock.yaml +++ b/dashboard/pnpm-lock.yaml @@ -248,6 +248,9 @@ importers: tailwindcss-animate: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.3) + use-debounce: + specifier: ^10.0.3 + version: 10.0.3(react@18.3.1) vaul: specifier: ^0.9.1 version: 0.9.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -8487,6 +8490,12 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 + use-debounce@10.0.3: + resolution: {integrity: sha512-DxQSI9ZKso689WM1mjgGU3ozcxU1TJElBJ3X6S4SMzMNcm2lVH0AHmyXB+K7ewjz2BSUKJTDqTcwtSMRfB89dg==} + engines: {node: '>= 16.0.0'} + peerDependencies: + react: '*' + use-deep-compare-effect@1.8.1: resolution: {integrity: sha512-kbeNVZ9Zkc0RFGpfMN3MNfaKNvcLNyxOAAd9O4CBZ+kCBXXscn9s/4I+8ytUER4RDpEYs5+O6Rs4PqiZ+rHr5Q==} engines: {node: '>=10', npm: '>=6'} @@ -19956,6 +19965,10 @@ snapshots: dependencies: react: 18.3.1 + use-debounce@10.0.3(react@18.3.1): + dependencies: + react: 18.3.1 + use-deep-compare-effect@1.8.1(react@18.3.1): dependencies: '@babel/runtime': 7.24.6 diff --git a/dashboard/src/features/admins/types/admin-prop.ts b/dashboard/src/features/admins/types/admin-prop.ts deleted file mode 100644 index 05220ad..0000000 --- a/dashboard/src/features/admins/types/admin-prop.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { AdminType } from "@marzneshin/features/admins"; - -export interface AdminProp { - admin: AdminType; -} diff --git a/dashboard/src/features/entity-table/components/column-header-combo-filter.tsx b/dashboard/src/features/entity-table/components/column-header-combo-filter.tsx index 8ac74e4..44eebd7 100644 --- a/dashboard/src/features/entity-table/components/column-header-combo-filter.tsx +++ b/dashboard/src/features/entity-table/components/column-header-combo-filter.tsx @@ -36,18 +36,14 @@ export function DataTableColumnHeaderFilterOption( const [selectedOption, setSelectedOption] = React.useState( null ) - const { filters, table } = useEntityTableContext(); + const { filters, table: { setPageIndex } } = useEntityTableContext(); function handleClearingFilter() { filters.setColumnsFilter({ ...filters.columnsFilter, [column.id]: undefined }); setSelectedOption(null); + setPageIndex(1); } - React.useEffect(() => { - // if (table.getState().pagination.pageIndex !== 1) - table.setPageIndex(1); - }, [table, selectedOption]) - if (isDesktop) { return ( @@ -69,7 +65,7 @@ export function DataTableColumnHeaderFilterOption( - + { setSelectedOption(value); setPageIndex(1); }} options={options} /> ) diff --git a/dashboard/src/features/entity-table/components/data-table.tsx b/dashboard/src/features/entity-table/components/data-table.tsx index 092baa2..5823893 100644 --- a/dashboard/src/features/entity-table/components/data-table.tsx +++ b/dashboard/src/features/entity-table/components/data-table.tsx @@ -5,7 +5,6 @@ import { RowSelectionState, SortingState, VisibilityState, - flexRender, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, @@ -15,19 +14,14 @@ import { import { Button, - Input, - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, } from "@marzneshin/components" import { useTranslation } from "react-i18next" import { DataTablePagination } from "./table-pagination" import { useState } from "react" import { DataTableViewOptions } from "./table-view-option" +import { TableSearch } from "./table-filtering" +import { EntityDataTable } from "./table"; interface DataTableProps { columns: ColumnDef[] @@ -44,7 +38,6 @@ export function DataTable({ data, onCreate, onOpen, - filteredColumn, selectedRow, setSelectedRow, }: DataTableProps) { @@ -76,61 +69,12 @@ export function DataTable({ return (
- - table.getColumn(filteredColumn)?.setFilterValue(event.target.value) - } - className="max-w-sm" - /> + {onCreate && ()}
- - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - return ( - - {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext() - )} - - ) - })} - - ))} - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => ( - onOpen !== undefined && onOpen(row.original)} - > - {row.getVisibleCells().map((cell) => ( - - {flexRender(cell.column.columnDef.cell, cell.getContext())} - - ))} - - )) - ) : ( - - - {t('table.no-result')} - - - )} - -
+
diff --git a/dashboard/src/features/entity-table/components/table-filtering.tsx b/dashboard/src/features/entity-table/components/table-filtering.tsx index bc2865d..2b63c16 100644 --- a/dashboard/src/features/entity-table/components/table-filtering.tsx +++ b/dashboard/src/features/entity-table/components/table-filtering.tsx @@ -1,21 +1,33 @@ - -import { type FC } from "react"; +import { type FC, useEffect, useState } from "react"; import { Input } from "@marzneshin/components"; import { useEntityTableContext } from "@marzneshin/features/entity-table/contexts"; import { useTranslation } from "react-i18next"; +import { useDebouncedCallback } from 'use-debounce'; interface TableSearchProps { } export const TableSearch: FC = () => { const { primaryFilter } = useEntityTableContext() + const [keyword, setKeyword] = useState(primaryFilter.columnFilters) + + const setColumnFilters = useDebouncedCallback( + primaryFilter.setColumnFilters, + 500 + ); + + useEffect(() => { + setColumnFilters(keyword); + }, [keyword, setColumnFilters]) + const { t } = useTranslation() + return ( primaryFilter.setColumnFilters(e.target.value)} + value={keyword} + onChange={(e) => setKeyword(e.target.value)} className=" w-full md:w-[20rem]" /> ); diff --git a/dashboard/src/features/entity-table/components/table.tsx b/dashboard/src/features/entity-table/components/table.tsx index b44e42f..6b8b47e 100644 --- a/dashboard/src/features/entity-table/components/table.tsx +++ b/dashboard/src/features/entity-table/components/table.tsx @@ -42,7 +42,7 @@ const Rows: FC>> = ({ const { table } = useEntityTableContext(); const { t } = useTranslation(); - return (table.getRowModel().rows.length ? ( + return (table.getRowModel().rows?.length ? ( table.getRowModel().rows.map(row => ( >> = ({ )) }; +const Loading = () => ( + <> + {Array.from({ length: 5 }).map((_, rowIndex) => ( + + + + + + + + + + + + + + + + + + ))} + +); + export function EntityDataTable({ columns, onRowClick, }: Readonly>) { const { isLoading } = useEntityTableContext(); - const Loading = () => ( - <> - {Array.from({ length: 5 }).map((_, rowIndex) => ( - - - - - - - - - - - - - - - - - - ))} - - ); - return ( diff --git a/dashboard/src/features/entity-table/double-entity-table.tsx b/dashboard/src/features/entity-table/double-entity-table.tsx new file mode 100644 index 0000000..c97ac50 --- /dev/null +++ b/dashboard/src/features/entity-table/double-entity-table.tsx @@ -0,0 +1,108 @@ +import { useMemo } from "react"; +import { Button } from "@marzneshin/components"; +import { DataTableViewOptions } from "./components"; +import { useTranslation } from "react-i18next"; +import { useQuery } from "@tanstack/react-query"; +import { ColumnDef } from "@tanstack/react-table"; +import { EntityTableContext } from "./contexts"; +import { TableSearch, DataTablePagination, EntityDataTable } from "./components"; +import { + usePrimaryFiltering, + usePagination, + useEntityTable, + useVisibility, + useSorting, + type UseRowSelectionReturn, + type FetchEntityReturn, + type DoubleEntityQueryKey, + type DoubleEntityQueryKeyType, + useFilters, +} from "./hooks"; + +export interface DoubleEntityTableProps { + columns: ColumnDef[]; + primaryFilter: string; + entityKey: string; + entityId: number; + rowSelection?: UseRowSelectionReturn; + fetchEntity: ({ queryKey }: DoubleEntityQueryKeyType) => FetchEntityReturn; + onCreate?: () => void; + onOpen?: (entity: any) => void; +} + +export function DoubleEntityTable({ + fetchEntity, + columns, + primaryFilter, + rowSelection, + entityKey, + entityId, + onCreate, + onOpen, +}: DoubleEntityTableProps) { + const { t } = useTranslation(); + const columnPrimaryFilter = usePrimaryFiltering({ column: primaryFilter }); + const filters = useFilters(); + const sorting = useSorting(); + const visibility = useVisibility(); + const { onPaginationChange, pageIndex, pageSize } = usePagination(); + + const query: DoubleEntityQueryKey = [ + entityKey, + entityId, + { + page: pageIndex, + size: pageSize, + }, + columnPrimaryFilter.columnFilters, + { + sortBy: sorting.sorting[0]?.id || "created_at", + desc: sorting.sorting[0]?.desc || true, + }, + { filters: filters.columnsFilter } + ]; + + const { data, isFetching } = useQuery({ + queryFn: fetchEntity, + queryKey: query, + initialData: { entities: [], pageCount: 1 }, + }); + + const table = useEntityTable({ + data, + columns, + pageSize, + pageIndex, + rowSelection, + visibility, + sorting, + onPaginationChange, + }); + + const contextValue = useMemo( + () => ({ table, data: data.entities, primaryFilter: columnPrimaryFilter, filters, isLoading: isFetching }), + [table, data.entities, filters, columnPrimaryFilter, isFetching], + ); + + return ( + +
+
+
+ + {onCreate && ( + + )} +
+ +
+
+ + +
+
+
+ ); +} diff --git a/dashboard/src/features/entity-table/entity-table.tsx b/dashboard/src/features/entity-table/entity-table.tsx index 0c9e260..1336f69 100644 --- a/dashboard/src/features/entity-table/entity-table.tsx +++ b/dashboard/src/features/entity-table/entity-table.tsx @@ -7,26 +7,26 @@ import { ColumnDef } from "@tanstack/react-table"; import { EntityTableContext } from "./contexts"; import { TableSearch, DataTablePagination, EntityDataTable } from "./components"; import { - type UseRowSelectionReturn, usePrimaryFiltering, usePagination, - type FetchEntityReturn, useEntityTable, useVisibility, useSorting, + type UseRowSelectionReturn, + type FetchEntityReturn, type QueryKey, type EntityQueryKeyType, useFilters, } from "./hooks"; export interface EntityTableProps { - fetchEntity: ({ queryKey }: EntityQueryKeyType) => FetchEntityReturn; columns: ColumnDef[]; primaryFilter: string; entityKey: string; rowSelection?: UseRowSelectionReturn; - onCreate: () => void; - onOpen: (entity: any) => void; + fetchEntity: ({ queryKey }: EntityQueryKeyType) => FetchEntityReturn; + onCreate?: () => void; + onOpen?: (entity: any) => void; } export function EntityTable({ @@ -44,6 +44,7 @@ export function EntityTable({ const sorting = useSorting(); const visibility = useVisibility(); const { onPaginationChange, pageIndex, pageSize } = usePagination(); + const query: QueryKey = [ entityKey, { @@ -61,7 +62,7 @@ export function EntityTable({ const { data, isFetching } = useQuery({ queryFn: fetchEntity, queryKey: query, - initialData: { entity: [], pageCount: 1 }, + initialData: { entities: [], pageCount: 1 }, }); const table = useEntityTable({ @@ -76,8 +77,8 @@ export function EntityTable({ }); const contextValue = useMemo( - () => ({ table, data: data.entity, primaryFilter: columnPrimaryFilter, filters, isLoading: isFetching }), - [table, data.entity, filters, columnPrimaryFilter, isFetching], + () => ({ table, data: data.entities, primaryFilter: columnPrimaryFilter, filters, isLoading: isFetching }), + [table, data.entities, filters, columnPrimaryFilter, isFetching], ); return ( diff --git a/dashboard/src/features/entity-table/hooks/use-entity-query.ts b/dashboard/src/features/entity-table/hooks/use-entity-query.ts index 19bc0fc..5448e05 100644 --- a/dashboard/src/features/entity-table/hooks/use-entity-query.ts +++ b/dashboard/src/features/entity-table/hooks/use-entity-query.ts @@ -1,5 +1,5 @@ -interface PaginatedEntityQueryProps { +export interface PaginatedEntityQueryProps { page: number; size: number; } @@ -20,11 +20,17 @@ interface FiltersEntityQueryProps { export type UseEntityQueryProps = Partial & PaginatedEntityQueryProps & Partial export type EntityName = string; +export type ParentEntityName = string; export type EntityId = number | string | undefined; export type PrimaryFilter = string; export type QueryKey = [EntityName, PaginatedEntityQueryProps, PrimaryFilter, SortedEntityQueryProps, FiltersEntityQueryProps] +export type DoubleEntityQueryKey = + [EntityName, EntityId, PaginatedEntityQueryProps, PrimaryFilter?, SortedEntityQueryProps?, FiltersEntityQueryProps?] + +export type SelectableQueryKey = + [ParentEntityName, EntityId, EntityName, PaginatedEntityQueryProps, PrimaryFilter, SortedEntityQueryProps, FiltersEntityQueryProps] export type SidebarQueryKey = [EntityName, EntityId, EntityName, PaginatedEntityQueryProps, PrimaryFilter, SortedEntityQueryProps, FiltersEntityQueryProps] @@ -34,11 +40,13 @@ export interface QueryKeyType { } export type EntityQueryKeyType = QueryKeyType +export type DoubleEntityQueryKeyType = QueryKeyType +export type SelectableEntityQueryKeyType = QueryKeyType export type EntitySidebarQueryKeyType = QueryKeyType interface FetchEntityResult { pageCount: number - entity: T[] + entities: T[] } export type FetchEntityReturn = Promise> diff --git a/dashboard/src/features/entity-table/hooks/use-entity-table.ts b/dashboard/src/features/entity-table/hooks/use-entity-table.ts index 148866a..6103974 100644 --- a/dashboard/src/features/entity-table/hooks/use-entity-table.ts +++ b/dashboard/src/features/entity-table/hooks/use-entity-table.ts @@ -18,7 +18,7 @@ import type { interface UseEntityTableProps { columns: ColumnDef[]; data: { - entity: TData[]; + entities: TData[]; pageCount: number; }; sorting: UseSortingReturn; @@ -42,7 +42,7 @@ export const useEntityTable = ({ onPaginationChange, }: UseEntityTableProps) => useReactTable({ - data: data.entity, + data: data.entities, columns, manualPagination: true, manualSorting, diff --git a/dashboard/src/features/entity-table/hooks/use-row-selection.ts b/dashboard/src/features/entity-table/hooks/use-row-selection.ts index 106f763..153305b 100644 --- a/dashboard/src/features/entity-table/hooks/use-row-selection.ts +++ b/dashboard/src/features/entity-table/hooks/use-row-selection.ts @@ -1,6 +1,13 @@ import { OnChangeFn, RowSelectionState } from "@tanstack/react-table" +import { useState } from "react"; export interface UseRowSelectionReturn { setSelectedRow: OnChangeFn selectedRow: RowSelectionState } + +export const useRowSelection = (state: RowSelectionState): UseRowSelectionReturn => { + const [selectedRow, setSelectedRow] = useState(state) + return { setSelectedRow, selectedRow } +} + diff --git a/dashboard/src/features/entity-table/hooks/use-sidebar-entity-table.ts b/dashboard/src/features/entity-table/hooks/use-sidebar-entity-table.ts index 8f429fb..4f9e3c7 100644 --- a/dashboard/src/features/entity-table/hooks/use-sidebar-entity-table.ts +++ b/dashboard/src/features/entity-table/hooks/use-sidebar-entity-table.ts @@ -79,7 +79,7 @@ export const useSidebarEntityTable = ({ const { data, isFetching } = useQuery({ queryFn: fetchEntity, queryKey: query, - initialData: { entity: [], pageCount: 1 }, + initialData: { entities: [], pageCount: 1 }, }); const columns = columnsFn({ onEdit, onDelete, onOpen }); @@ -95,8 +95,8 @@ export const useSidebarEntityTable = ({ }); const entityTableContextValue = useMemo( - () => ({ table, data: data.entity, primaryFilter, filters, isLoading: isFetching }), - [table, data.entity, filters, primaryFilter, isFetching], + () => ({ table, data: data.entities, primaryFilter, filters, isLoading: isFetching }), + [table, data.entities, filters, primaryFilter, isFetching], ); const sidebarEntityTableContextValue = useMemo( diff --git a/dashboard/src/features/entity-table/index.ts b/dashboard/src/features/entity-table/index.ts index 945c520..eb0cdb7 100644 --- a/dashboard/src/features/entity-table/index.ts +++ b/dashboard/src/features/entity-table/index.ts @@ -1,5 +1,7 @@ export * from "./entity-table"; +export * from "./selectable-entity-table"; export * from "./components"; export * from "./sidebar-entity-table"; +export * from "./double-entity-table"; export * from "./hooks"; export * from "./types"; diff --git a/dashboard/src/features/entity-table/selectable-entity-table.tsx b/dashboard/src/features/entity-table/selectable-entity-table.tsx new file mode 100644 index 0000000..af1a5dc --- /dev/null +++ b/dashboard/src/features/entity-table/selectable-entity-table.tsx @@ -0,0 +1,133 @@ +import { useEffect, useMemo } from "react"; +import { DataTableViewOptions } from "./components"; +import { useQuery } from "@tanstack/react-query"; +import { RowSelectionState, ColumnDef } from "@tanstack/react-table"; +import { EntityTableContext } from "./contexts"; +import { TableSearch, DataTablePagination, EntityDataTable } from "./components"; +import { + type UseRowSelectionReturn, + usePrimaryFiltering, + usePagination, + type FetchEntityReturn, + useEntityTable, + useVisibility, + useSorting, + type SelectableQueryKey, + type SelectableEntityQueryKeyType, + useFilters, +} from "./hooks"; + +export interface SelectableEntityTableProps { + fetchEntity: ({ queryKey }: SelectableEntityQueryKeyType) => FetchEntityReturn; + columns: ColumnDef[]; + primaryFilter: string; + parentEntityKey: string; + parentEntityId: string | number; + entityKey: string; + rowSelection: UseRowSelectionReturn; + entitySelection: { + selectedEntity: number[]; + setSelectedEntity: (s: number[]) => void; + } + existingEntityIds: number[]; +} + +export function SelectableEntityTable({ + fetchEntity, + columns, + primaryFilter, + rowSelection, + entitySelection, + entityKey, + parentEntityKey, + parentEntityId, + existingEntityIds, +}: SelectableEntityTableProps) { + const columnPrimaryFilter = usePrimaryFiltering({ column: primaryFilter }); + const filters = useFilters(); + const sorting = useSorting(); + const visibility = useVisibility(); + const { selectedRow, setSelectedRow } = rowSelection; + const { setSelectedEntity } = entitySelection; + const { onPaginationChange, pageIndex, pageSize } = usePagination(); + const query: SelectableQueryKey = [ + parentEntityKey, + parentEntityId, + entityKey, + { + page: pageIndex, + size: pageSize, + }, + columnPrimaryFilter.columnFilters, + { + sortBy: sorting.sorting[0]?.id || "created_at", + desc: sorting.sorting[0]?.desc || true, + }, + { filters: filters.columnsFilter } + ]; + + const { data, isFetching } = useQuery({ + queryFn: fetchEntity, + queryKey: query, + initialData: { entities: [], pageCount: 1 }, + }); + + const table = useEntityTable({ + data, + columns, + pageSize, + pageIndex, + rowSelection, + visibility, + sorting, + onPaginationChange, + }); + + useEffect(() => { + setSelectedRow((selected) => { + const updatedSelected: RowSelectionState = { ...selected }; + for (const [i, fetchedEntity] of data.entities.entries()) { + if (existingEntityIds.includes(fetchedEntity.id)) { + updatedSelected[i] = true; + } else { + updatedSelected[i] = false; + } + } + return updatedSelected; + }); + + }, [data, setSelectedRow, existingEntityIds]); + + useEffect(() => { + const selectedRowId = Object.keys(selectedRow).filter(key => selectedRow[key] === true).map(Number); + + setSelectedEntity( + selectedRowId + .map(id => data.entities[id]?.id) + .filter(id => id !== null && id !== undefined) + ); + }, [data, setSelectedEntity, setSelectedRow, existingEntityIds, selectedRow]); + + + const contextValue = useMemo( + () => ({ table, data: data.entities, primaryFilter: columnPrimaryFilter, filters, isLoading: isFetching }), + [table, data.entities, filters, columnPrimaryFilter, isFetching], + ); + + return ( + +
+
+
+ +
+ +
+
+ + +
+
+
+ ); +} diff --git a/dashboard/src/features/entity-table/stories/fetch-entities.ts b/dashboard/src/features/entity-table/stories/fetch-entities.ts index 953ce97..719e0b7 100644 --- a/dashboard/src/features/entity-table/stories/fetch-entities.ts +++ b/dashboard/src/features/entity-table/stories/fetch-entities.ts @@ -64,7 +64,7 @@ export const fetchEntity = async ({ queryKey }: { queryKey: any }) => { const paginatedEntities = filteredEntities.slice(startIndex, endIndex); return { - entity: paginatedEntities, + entities: paginatedEntities, pageCount: Math.ceil(filteredEntities.length / pageSize), }; } @@ -73,7 +73,7 @@ export const fetchEntityLoading = async (): FetchEntityReturn => { return new Promise((resolve) => { setTimeout(() => { resolve({ - entity: [{ id: 40, name: "Diyar Latif", createdAt: "2026-04-13" }], + entities: [{ id: 40, name: "Diyar Latif", createdAt: "2026-04-13" }], pageCount: 1, }); }, 24 * 60 * 60 * 1000); diff --git a/dashboard/src/features/hosts/services/hosts.query.ts b/dashboard/src/features/hosts/services/hosts.query.ts index 07c3008..6683bbb 100644 --- a/dashboard/src/features/hosts/services/hosts.query.ts +++ b/dashboard/src/features/hosts/services/hosts.query.ts @@ -21,7 +21,7 @@ export async function fetchHosts({ queryKey }: EntitySidebarQueryKeyType): Fetch } }).then((result) => { return { - entity: result.items, + entities: result.items, pageCount: result.pages }; }); @@ -35,6 +35,6 @@ export const useHostsQuery = ({ return useQuery({ queryKey: ["inbounds", inboundId, HostsQueryFetchKey, { page, size }, filters?.username ?? "", { sortBy, desc }, { filters }], queryFn: fetchHosts, - initialData: { entity: [], pageCount: 0 } + initialData: { entities: [], pageCount: 0 } }) } diff --git a/dashboard/src/features/hosts/tables/inbound-hosts/index.tsx b/dashboard/src/features/hosts/tables/inbound-hosts/index.tsx index b420f55..a3d1486 100644 --- a/dashboard/src/features/hosts/tables/inbound-hosts/index.tsx +++ b/dashboard/src/features/hosts/tables/inbound-hosts/index.tsx @@ -19,8 +19,8 @@ import { } from "./inbound-sidebar-card"; export const InboundHostsTable = () => { - const { data: inbounds } = useInboundsQuery() - const [selectedInbound, setSelectedInbound] = useState(inbounds[0]?.id !== undefined ? String(inbounds[0].id) : undefined) + const { data } = useInboundsQuery({ page: 1, size: 100 }) + const [selectedInbound, setSelectedInbound] = useState(data.entities[0]?.id !== undefined ? String(data.entities[0].id) : undefined) const navigate = useNavigate({ from: "/hosts" }) const [inboundSelectionAlert, setInboundSelectionAlert] = useDialog(); @@ -51,7 +51,7 @@ export const InboundHostsTable = () => { fetchEntity={fetchHosts} entityKey="inbounds" secondaryEntityKey="hosts" - sidebarEntities={inbounds} + sidebarEntities={data.entities} sidebarEntityId={selectedInbound} columnsFn={columns} filteredColumn='remark' diff --git a/dashboard/src/features/inbounds/services/inbounds.query.ts b/dashboard/src/features/inbounds/services/inbounds.query.ts index 6cb6ffc..22db81b 100644 --- a/dashboard/src/features/inbounds/services/inbounds.query.ts +++ b/dashboard/src/features/inbounds/services/inbounds.query.ts @@ -1,20 +1,41 @@ import { useQuery } from "@tanstack/react-query"; import { fetch } from "@marzneshin/utils"; +import { + FetchEntityReturn, + UseEntityQueryProps, + EntityQueryKeyType +} from "@marzneshin/features/entity-table"; import { InboundType } from "../types"; -export async function fetchInbounds(): Promise { - return fetch('/inbounds').then((result) => { - return result.items - }); +export async function fetchInbounds({ queryKey }: EntityQueryKeyType): FetchEntityReturn { + const pagination = queryKey[1]; + const primaryFilter = queryKey[2]; + const filters = queryKey[4].filters; + return fetch(`/inbounds`, { + query: { + ...pagination, + ...filters, + tag: primaryFilter, + descending: queryKey[3].desc, + order_by: queryKey[3].sortBy, + } + }).then((result) => { + return { + entities: result.items, + pageCount: result.pages + }; + }) } export const InboundsQueryFetchKey = "inbounds"; -export const useInboundsQuery = () => { +export const useInboundsQuery = ({ + page, size, sortBy = "created_at", desc = false, filters = {} +}: UseEntityQueryProps) => { return useQuery({ - queryKey: [InboundsQueryFetchKey], + queryKey: [InboundsQueryFetchKey, { page, size }, filters?.tag ?? "", { sortBy, desc }, { filters }], queryFn: fetchInbounds, - initialData: [] + initialData: { entities: [], pageCount: 0 } }) } diff --git a/dashboard/src/features/nodes/services/nodes.query.ts b/dashboard/src/features/nodes/services/nodes.query.ts index 6602fbd..ae6a8c7 100644 --- a/dashboard/src/features/nodes/services/nodes.query.ts +++ b/dashboard/src/features/nodes/services/nodes.query.ts @@ -4,15 +4,16 @@ import { fetch } from "@marzneshin/utils"; import type { EntityQueryKeyType, UseEntityQueryProps, + FetchEntityReturn } from "@marzneshin/features/entity-table"; export async function fetchNodes({ queryKey, -}: EntityQueryKeyType): Promise<{ entity: NodeType[]; pageCount: number }> { +}: EntityQueryKeyType): FetchEntityReturn { const pagination = queryKey[1]; const primaryFilter = queryKey[2]; const filters = queryKey[4].filters; - return fetch(`/nodes`, { + return fetch('/nodes', { query: { ...pagination, ...filters, @@ -22,7 +23,7 @@ export async function fetchNodes({ } }).then((result) => { return { - entity: result.items, + entities: result.items, pageCount: result.pages, }; }); @@ -36,6 +37,6 @@ export const useNodesQuery = ({ return useQuery({ queryKey: [NodesQueryFetchKey, { page, size }, filters?.username ?? "", { sortBy, desc }, { filters }], queryFn: fetchNodes, - initialData: { entity: [], pageCount: 0 }, + initialData: { entities: [], pageCount: 0 }, }); }; diff --git a/dashboard/src/features/services/components/dialogs/mutation/fields/inbounds.tsx b/dashboard/src/features/services/components/dialogs/mutation/fields/inbounds.tsx index b13e192..def8cd1 100644 --- a/dashboard/src/features/services/components/dialogs/mutation/fields/inbounds.tsx +++ b/dashboard/src/features/services/components/dialogs/mutation/fields/inbounds.tsx @@ -61,7 +61,7 @@ export const InboundCard = ({ }; export const InboundsField = () => { - const { data: inbounds } = useInboundsQuery(); + const { data } = useInboundsQuery({ page: 1, size: 100 }); const form = useFormContext(); const { t } = useTranslation(); @@ -73,7 +73,7 @@ export const InboundsField = () => { {t("inbounds")} - {inbounds.map((inbound) => ( + {data.entities.map((inbound) => ( { } - isNotFound={data.entity.length === 0} + isNotFound={data.entities.length === 0} NotFound={} - Component={} + Component={} /> )} diff --git a/dashboard/src/features/services/components/tables/inbounds/index.tsx b/dashboard/src/features/services/components/tables/inbounds/index.tsx index 1e8aeec..613b57d 100644 --- a/dashboard/src/features/services/components/tables/inbounds/index.tsx +++ b/dashboard/src/features/services/components/tables/inbounds/index.tsx @@ -1,11 +1,9 @@ -import { type FC, useCallback, useEffect, useState } from "react"; -import { useInboundsQuery } from "@marzneshin/features/inbounds"; +import { type FC, useCallback, useState } from "react"; import { Button } from "@marzneshin/components"; -import { DataTable } from "@marzneshin/features/entity-table"; +import { SelectableEntityTable, useRowSelection } from "@marzneshin/features/entity-table"; import { columns } from "./columns"; -import { type ServiceType, useServicesUpdateMutation } from "@marzneshin/features/services"; +import { type ServiceType, useServicesUpdateMutation, fetchSelectableServiceInbounds } from "@marzneshin/features/services"; import { useTranslation } from "react-i18next"; -import type { RowSelectionState } from "@tanstack/react-table"; interface ServiceInboundsTableProps { service: ServiceType; @@ -15,43 +13,30 @@ export const ServiceInboundsTable: FC = ({ service, }) => { const { mutate: updateService } = useServicesUpdateMutation(); - const { data } = useInboundsQuery(); - const [selectedInbound, setSelectedInbound] = useState<{ - [key: number]: boolean; - }>({}); + const { selectedRow, setSelectedRow } = + useRowSelection(Object.fromEntries(service.inbound_ids.map(entityId => [String(entityId), true]))); + const [selectedInbound, setSelectedInbound] = useState(service.inbound_ids); const { t } = useTranslation(); - useEffect(() => { - setSelectedInbound((prevSelected) => { - const updatedSelected: RowSelectionState = { ...prevSelected }; - for (const inboundId of service.inbound_ids) { - for (const [i, fetchedInbound] of data.entries()) { - if (fetchedInbound.id === inboundId) { - updatedSelected[i] = true; - } - } - } - return updatedSelected; - }); - }, [data, service.inbound_ids]); - const handleApply = useCallback(() => { - const selectedInboundIds = Object.keys(selectedInbound) - .filter((key) => selectedInbound[Number.parseInt(key)]) - .map((key) => data[Number.parseInt(key)].id); - updateService({ ...service, inbound_ids: selectedInboundIds }); - }, [data, selectedInbound, service, updateService]); + console.log(selectedInbound) + updateService({ id: service.id, name: service.name, inbound_ids: selectedInbound }); + }, [selectedInbound, service, updateService]); - const disabled = Object.keys(selectedInbound).length < 1; + const disabled = Object.keys(selectedRow).length < 1; return (
-
diff --git a/dashboard/src/features/users/components/tables/users/columns.tsx b/dashboard/src/features/users/components/tables/users/columns.tsx index 2cb2bad..09db732 100644 --- a/dashboard/src/features/users/components/tables/users/columns.tsx +++ b/dashboard/src/features/users/components/tables/users/columns.tsx @@ -6,7 +6,7 @@ import { UserExpireStrategyPill, UserExpirationValue } from "@marzneshin/features/users"; -import { useAdminsQuery } from "@marzneshin/features/admins"; +import { useAdminsQuery } from "@marzneshin/modules/admins"; import i18n from "@marzneshin/features/i18n"; import { CopyToClipboardButton, @@ -111,7 +111,7 @@ function AdminsColumnsHeaderOptionFilter({ column }: { column: Co admin.username)} + options={data.entities.map((admin) => admin.username)} /> ); } diff --git a/dashboard/src/features/users/services/user.query.ts b/dashboard/src/features/users/services/user.query.ts index 1838d13..72da827 100644 --- a/dashboard/src/features/users/services/user.query.ts +++ b/dashboard/src/features/users/services/user.query.ts @@ -19,9 +19,5 @@ export const userQueryOptions = ({ username }: { username: string }) => { }; export const useUserQuery = ({ username }: { username: string }) => { - return useQuery({ - queryKey: [UserQueryFetchKey, username], - queryFn: fetchUser, - initialData: null, - }); + return useQuery(userQueryOptions({ username })); }; diff --git a/dashboard/src/features/users/services/users.query.ts b/dashboard/src/features/users/services/users.query.ts index 3c3a5d6..e05f298 100644 --- a/dashboard/src/features/users/services/users.query.ts +++ b/dashboard/src/features/users/services/users.query.ts @@ -24,7 +24,7 @@ export async function fetchUsers({ queryKey }: EntityQueryKeyType): FetchEntityR } }).then((result) => { return { - entity: result.items, + entities: result.items, pageCount: result.pages }; }); @@ -38,6 +38,6 @@ export const useUsersQuery = ({ return useQuery({ queryKey: [UsersQueryFetchKey, { page, size }, filters?.username ?? "", { sortBy, desc }, { filters }], queryFn: fetchUsers, - initialData: { entity: [], pageCount: 0 } + initialData: { entities: [], pageCount: 0 } }) } diff --git a/dashboard/src/features/admins/components/dialogs/delete-confirmation/index.tsx b/dashboard/src/modules/admins/components/dialogs/delete-confirmation/index.tsx similarity index 95% rename from dashboard/src/features/admins/components/dialogs/delete-confirmation/index.tsx rename to dashboard/src/modules/admins/components/dialogs/delete-confirmation/index.tsx index 1a0e4e2..c2c8b05 100644 --- a/dashboard/src/features/admins/components/dialogs/delete-confirmation/index.tsx +++ b/dashboard/src/modules/admins/components/dialogs/delete-confirmation/index.tsx @@ -3,7 +3,7 @@ import { type FC, useEffect } from "react"; import { type AdminType, useAdminsDeletionMutation, -} from "@marzneshin/features/admins"; +} from "@marzneshin/modules/admins"; interface AdminsDeleteConfirmationDialogProps { onOpenChange: (state: boolean) => void; diff --git a/dashboard/src/features/admins/components/dialogs/index.ts b/dashboard/src/modules/admins/components/dialogs/index.ts similarity index 100% rename from dashboard/src/features/admins/components/dialogs/index.ts rename to dashboard/src/modules/admins/components/dialogs/index.ts diff --git a/dashboard/src/features/admins/components/dialogs/mutation/fields/all-services-access.tsx b/dashboard/src/modules/admins/components/dialogs/mutation/fields/all-services-access.tsx similarity index 100% rename from dashboard/src/features/admins/components/dialogs/mutation/fields/all-services-access.tsx rename to dashboard/src/modules/admins/components/dialogs/mutation/fields/all-services-access.tsx diff --git a/dashboard/src/features/admins/components/dialogs/mutation/fields/enabled.tsx b/dashboard/src/modules/admins/components/dialogs/mutation/fields/enabled.tsx similarity index 100% rename from dashboard/src/features/admins/components/dialogs/mutation/fields/enabled.tsx rename to dashboard/src/modules/admins/components/dialogs/mutation/fields/enabled.tsx diff --git a/dashboard/src/features/admins/components/dialogs/mutation/fields/index.ts b/dashboard/src/modules/admins/components/dialogs/mutation/fields/index.ts similarity index 100% rename from dashboard/src/features/admins/components/dialogs/mutation/fields/index.ts rename to dashboard/src/modules/admins/components/dialogs/mutation/fields/index.ts diff --git a/dashboard/src/features/admins/components/dialogs/mutation/fields/modify-users-access.tsx b/dashboard/src/modules/admins/components/dialogs/mutation/fields/modify-users-access.tsx similarity index 100% rename from dashboard/src/features/admins/components/dialogs/mutation/fields/modify-users-access.tsx rename to dashboard/src/modules/admins/components/dialogs/mutation/fields/modify-users-access.tsx diff --git a/dashboard/src/features/admins/components/dialogs/mutation/fields/password.tsx b/dashboard/src/modules/admins/components/dialogs/mutation/fields/password.tsx similarity index 100% rename from dashboard/src/features/admins/components/dialogs/mutation/fields/password.tsx rename to dashboard/src/modules/admins/components/dialogs/mutation/fields/password.tsx diff --git a/dashboard/src/features/admins/components/dialogs/mutation/fields/subscription-url-prefix.tsx b/dashboard/src/modules/admins/components/dialogs/mutation/fields/subscription-url-prefix.tsx similarity index 100% rename from dashboard/src/features/admins/components/dialogs/mutation/fields/subscription-url-prefix.tsx rename to dashboard/src/modules/admins/components/dialogs/mutation/fields/subscription-url-prefix.tsx diff --git a/dashboard/src/features/admins/components/dialogs/mutation/fields/sudo-privilage.tsx b/dashboard/src/modules/admins/components/dialogs/mutation/fields/sudo-privilage.tsx similarity index 100% rename from dashboard/src/features/admins/components/dialogs/mutation/fields/sudo-privilage.tsx rename to dashboard/src/modules/admins/components/dialogs/mutation/fields/sudo-privilage.tsx diff --git a/dashboard/src/features/admins/components/dialogs/mutation/index.tsx b/dashboard/src/modules/admins/components/dialogs/mutation/index.tsx similarity index 98% rename from dashboard/src/features/admins/components/dialogs/mutation/index.tsx rename to dashboard/src/modules/admins/components/dialogs/mutation/index.tsx index be4d56e..1b96af2 100644 --- a/dashboard/src/features/admins/components/dialogs/mutation/index.tsx +++ b/dashboard/src/modules/admins/components/dialogs/mutation/index.tsx @@ -16,7 +16,7 @@ import { AdminEditSchema, AdminCreateSchema, AdminType, -} from "@marzneshin/features/admins"; +} from "@marzneshin/modules/admins"; import { ServicesField } from "@marzneshin/features/services"; import { UsernameField } from "@marzneshin/features/users"; import { diff --git a/dashboard/src/features/admins/components/dialogs/settings/admin-info/index.ts b/dashboard/src/modules/admins/components/dialogs/settings/admin-info/index.ts similarity index 100% rename from dashboard/src/features/admins/components/dialogs/settings/admin-info/index.ts rename to dashboard/src/modules/admins/components/dialogs/settings/admin-info/index.ts diff --git a/dashboard/src/features/admins/components/dialogs/settings/admin-info/table.tsx b/dashboard/src/modules/admins/components/dialogs/settings/admin-info/table.tsx similarity index 97% rename from dashboard/src/features/admins/components/dialogs/settings/admin-info/table.tsx rename to dashboard/src/modules/admins/components/dialogs/settings/admin-info/table.tsx index 10ed23d..02812f3 100644 --- a/dashboard/src/features/admins/components/dialogs/settings/admin-info/table.tsx +++ b/dashboard/src/modules/admins/components/dialogs/settings/admin-info/table.tsx @@ -12,7 +12,7 @@ import { type AdminProp, AdminEnabledPill, AdminPermissionPill -} from "@marzneshin/features/admins"; +} from "@marzneshin/modules/admins"; import { useTranslation } from "react-i18next"; import { format } from '@chbphone55/pretty-bytes'; diff --git a/dashboard/src/features/admins/components/dialogs/settings/index.tsx b/dashboard/src/modules/admins/components/dialogs/settings/index.tsx similarity index 96% rename from dashboard/src/features/admins/components/dialogs/settings/index.tsx rename to dashboard/src/modules/admins/components/dialogs/settings/index.tsx index 60b31f8..8af5dd4 100644 --- a/dashboard/src/features/admins/components/dialogs/settings/index.tsx +++ b/dashboard/src/modules/admins/components/dialogs/settings/index.tsx @@ -1,5 +1,4 @@ import { - // Button, Tabs, TabsContent, TabsList, @@ -9,7 +8,7 @@ import { SettingsDialogProps, SettingsDialog, } from "@marzneshin/components"; -import { type AdminType } from "@marzneshin/features/admins"; +import { type AdminType } from "@marzneshin/modules/admins"; import { type FC } from "react"; import { AdminInfoTable } from "./admin-info"; import { useTranslation } from "react-i18next"; diff --git a/dashboard/src/features/admins/components/index.ts b/dashboard/src/modules/admins/components/index.ts similarity index 100% rename from dashboard/src/features/admins/components/index.ts rename to dashboard/src/modules/admins/components/index.ts diff --git a/dashboard/src/features/admins/components/pills/admin-enabled-pill.tsx b/dashboard/src/modules/admins/components/pills/admin-enabled-pill.tsx similarity index 87% rename from dashboard/src/features/admins/components/pills/admin-enabled-pill.tsx rename to dashboard/src/modules/admins/components/pills/admin-enabled-pill.tsx index 4ca3943..19d8dc5 100644 --- a/dashboard/src/features/admins/components/pills/admin-enabled-pill.tsx +++ b/dashboard/src/modules/admins/components/pills/admin-enabled-pill.tsx @@ -1,7 +1,7 @@ import { type FC } from "react"; import { BooleanPill } from "@marzneshin/components"; import { useTranslation } from "react-i18next"; -import { AdminProp } from "@marzneshin/features/admins"; +import { AdminProp } from "@marzneshin/modules/admins"; export const AdminEnabledPill: FC = ({ admin }) => { const { t } = useTranslation(); diff --git a/dashboard/src/features/admins/components/pills/admin-permission-pill.tsx b/dashboard/src/modules/admins/components/pills/admin-permission-pill.tsx similarity index 89% rename from dashboard/src/features/admins/components/pills/admin-permission-pill.tsx rename to dashboard/src/modules/admins/components/pills/admin-permission-pill.tsx index 5fbf539..ac1b340 100644 --- a/dashboard/src/features/admins/components/pills/admin-permission-pill.tsx +++ b/dashboard/src/modules/admins/components/pills/admin-permission-pill.tsx @@ -1,7 +1,7 @@ import { type FC } from "react"; import { BooleanPill } from "@marzneshin/components"; import { useTranslation } from "react-i18next"; -import { AdminProp } from "@marzneshin/features/admins"; +import { AdminProp } from "@marzneshin/modules/admins"; export const AdminPermissionPill: FC = ({ admin }) => { const { t } = useTranslation(); diff --git a/dashboard/src/features/admins/components/pills/index.ts b/dashboard/src/modules/admins/components/pills/index.ts similarity index 100% rename from dashboard/src/features/admins/components/pills/index.ts rename to dashboard/src/modules/admins/components/pills/index.ts diff --git a/dashboard/src/features/admins/components/tables/admins/columns.tsx b/dashboard/src/modules/admins/components/tables/admins/columns.tsx similarity index 97% rename from dashboard/src/features/admins/components/tables/admins/columns.tsx rename to dashboard/src/modules/admins/components/tables/admins/columns.tsx index b206d2f..993d9b9 100644 --- a/dashboard/src/features/admins/components/tables/admins/columns.tsx +++ b/dashboard/src/modules/admins/components/tables/admins/columns.tsx @@ -3,7 +3,7 @@ import { type AdminType, AdminEnabledPill, AdminPermissionPill, -} from "@marzneshin/features/admins"; +} from "@marzneshin/modules/admins"; import { DataTableActionsCell, DataTableColumnHeader diff --git a/dashboard/src/features/admins/components/tables/admins/index.tsx b/dashboard/src/modules/admins/components/tables/admins/index.tsx similarity index 97% rename from dashboard/src/features/admins/components/tables/admins/index.tsx rename to dashboard/src/modules/admins/components/tables/admins/index.tsx index c1787d5..9c124d1 100644 --- a/dashboard/src/features/admins/components/tables/admins/index.tsx +++ b/dashboard/src/modules/admins/components/tables/admins/index.tsx @@ -1,6 +1,6 @@ import type { FC } from "react"; import { ColumnDef } from "@tanstack/react-table"; -import { fetchAdmins, AdminType, AdminsQueryFetchKey } from "@marzneshin/features/admins"; +import { fetchAdmins, AdminType, AdminsQueryFetchKey } from "@marzneshin/modules/admins"; import { columns as columnsFn } from "./columns"; import { EntityTable } from "@marzneshin/features/entity-table"; import { useNavigate } from "@tanstack/react-router"; diff --git a/dashboard/src/features/admins/components/tables/index.ts b/dashboard/src/modules/admins/components/tables/index.ts similarity index 100% rename from dashboard/src/features/admins/components/tables/index.ts rename to dashboard/src/modules/admins/components/tables/index.ts diff --git a/dashboard/src/features/admins/contexts/router.ts b/dashboard/src/modules/admins/contexts/router.ts similarity index 85% rename from dashboard/src/features/admins/contexts/router.ts rename to dashboard/src/modules/admins/contexts/router.ts index 41933a5..1198e98 100644 --- a/dashboard/src/features/admins/contexts/router.ts +++ b/dashboard/src/modules/admins/contexts/router.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from "react"; -import { AdminType } from "@marzneshin/features/admins"; +import { AdminType } from "@marzneshin/modules/admins"; interface RouterAdminContextProps { admin: AdminType | null; diff --git a/dashboard/src/features/admins/index.ts b/dashboard/src/modules/admins/index.ts similarity index 100% rename from dashboard/src/features/admins/index.ts rename to dashboard/src/modules/admins/index.ts diff --git a/dashboard/src/features/admins/services/admin.query.ts b/dashboard/src/modules/admins/services/admin.query.ts similarity index 100% rename from dashboard/src/features/admins/services/admin.query.ts rename to dashboard/src/modules/admins/services/admin.query.ts diff --git a/dashboard/src/features/admins/services/admins.query.ts b/dashboard/src/modules/admins/services/admins.query.ts similarity index 88% rename from dashboard/src/features/admins/services/admins.query.ts rename to dashboard/src/modules/admins/services/admins.query.ts index 51d23c2..81c9c79 100644 --- a/dashboard/src/features/admins/services/admins.query.ts +++ b/dashboard/src/modules/admins/services/admins.query.ts @@ -1,6 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import { fetch } from "@marzneshin/utils"; -import { AdminType } from "@marzneshin/features/admins"; +import { AdminType } from "@marzneshin/modules/admins"; import { FetchEntityReturn, UseEntityQueryProps, @@ -21,7 +21,7 @@ export async function fetchAdmins({ queryKey }: EntityQueryKeyType): FetchEntity } }).then((result) => { return { - entity: result.items, + entities: result.items, pageCount: result.pages }; }); @@ -35,6 +35,6 @@ export const useAdminsQuery = ({ return useQuery({ queryKey: [AdminsQueryFetchKey, { page, size }, filters?.username ?? "", { sortBy, desc }, { filters }], queryFn: fetchAdmins, - initialData: { entity: [], pageCount: 0 } + initialData: { entities: [], pageCount: 0 } }) } diff --git a/dashboard/src/features/admins/services/create-admin.mutate.ts b/dashboard/src/modules/admins/services/create-admin.mutate.ts similarity index 97% rename from dashboard/src/features/admins/services/create-admin.mutate.ts rename to dashboard/src/modules/admins/services/create-admin.mutate.ts index 50e77ad..fed6527 100644 --- a/dashboard/src/features/admins/services/create-admin.mutate.ts +++ b/dashboard/src/modules/admins/services/create-admin.mutate.ts @@ -1,4 +1,4 @@ -import { AdminType, AdminMutationType, AdminsQueryFetchKey } from "@marzneshin/features/admins"; +import { AdminType, AdminMutationType, AdminsQueryFetchKey } from "@marzneshin/modules/admins"; import { useMutation } from "@tanstack/react-query"; import { fetch, queryClient } from "@marzneshin/utils"; import { toast } from "sonner"; diff --git a/dashboard/src/features/admins/services/delete-admin.mutate.ts b/dashboard/src/modules/admins/services/delete-admin.mutate.ts similarity index 93% rename from dashboard/src/features/admins/services/delete-admin.mutate.ts rename to dashboard/src/modules/admins/services/delete-admin.mutate.ts index 1d6c7e8..d00e7b3 100644 --- a/dashboard/src/features/admins/services/delete-admin.mutate.ts +++ b/dashboard/src/modules/admins/services/delete-admin.mutate.ts @@ -1,4 +1,4 @@ -import { AdminType, AdminsQueryFetchKey } from "@marzneshin/features/admins"; +import { AdminType, AdminsQueryFetchKey } from "@marzneshin/modules/admins"; import { useMutation } from "@tanstack/react-query"; import { fetch, queryClient } from "@marzneshin/utils"; import { toast } from "sonner"; diff --git a/dashboard/src/features/admins/services/index.ts b/dashboard/src/modules/admins/services/index.ts similarity index 100% rename from dashboard/src/features/admins/services/index.ts rename to dashboard/src/modules/admins/services/index.ts diff --git a/dashboard/src/features/admins/services/update-admin.mutate.ts b/dashboard/src/modules/admins/services/update-admin.mutate.ts similarity index 97% rename from dashboard/src/features/admins/services/update-admin.mutate.ts rename to dashboard/src/modules/admins/services/update-admin.mutate.ts index 5cac34a..e2ca624 100644 --- a/dashboard/src/features/admins/services/update-admin.mutate.ts +++ b/dashboard/src/modules/admins/services/update-admin.mutate.ts @@ -6,7 +6,7 @@ import { AdminsQueryFetchKey, AdminMutationType, AdminType -} from "@marzneshin/features/admins"; +} from "@marzneshin/modules/admins"; export async function updateAdmin(admin: AdminMutationType): Promise { return fetch(`/admins/${admin.username}`, { method: 'put', body: admin }).then((admin) => { diff --git a/dashboard/src/modules/admins/types/admin-prop.ts b/dashboard/src/modules/admins/types/admin-prop.ts new file mode 100644 index 0000000..e6c7f4e --- /dev/null +++ b/dashboard/src/modules/admins/types/admin-prop.ts @@ -0,0 +1,5 @@ +import { AdminType } from "@marzneshin/modules/admins"; + +export interface AdminProp { + admin: AdminType; +} diff --git a/dashboard/src/features/admins/types/admin.ts b/dashboard/src/modules/admins/types/admin.ts similarity index 100% rename from dashboard/src/features/admins/types/admin.ts rename to dashboard/src/modules/admins/types/admin.ts diff --git a/dashboard/src/features/admins/types/index.ts b/dashboard/src/modules/admins/types/index.ts similarity index 100% rename from dashboard/src/features/admins/types/index.ts rename to dashboard/src/modules/admins/types/index.ts diff --git a/dashboard/src/features/admins/types/schema.ts b/dashboard/src/modules/admins/types/schema.ts similarity index 100% rename from dashboard/src/features/admins/types/schema.ts rename to dashboard/src/modules/admins/types/schema.ts diff --git a/dashboard/src/routes/_dashboard/admins.lazy.tsx b/dashboard/src/routes/_dashboard/admins.lazy.tsx index 881498b..9f334e5 100644 --- a/dashboard/src/routes/_dashboard/admins.lazy.tsx +++ b/dashboard/src/routes/_dashboard/admins.lazy.tsx @@ -8,7 +8,7 @@ import { } from '@marzneshin/components'; import { SudoRoute } from '@marzneshin/features/sudo-routes' import { createFileRoute, Outlet } from '@tanstack/react-router' -import { AdminsTable } from '@marzneshin/features/admins' +import { AdminsTable } from '@marzneshin/modules/admins' import { type FC, Suspense } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/dashboard/src/routes/_dashboard/admins/$adminId.tsx b/dashboard/src/routes/_dashboard/admins/$adminId.tsx index 828be3b..0786638 100644 --- a/dashboard/src/routes/_dashboard/admins/$adminId.tsx +++ b/dashboard/src/routes/_dashboard/admins/$adminId.tsx @@ -7,7 +7,7 @@ import { queryClient } from "@marzneshin/utils"; import { RouterAdminContext, adminQueryOptions, -} from "@marzneshin/features/admins"; +} from "@marzneshin/modules/admins"; import { Suspense, useMemo } from "react"; import { AlertDialog, diff --git a/dashboard/src/routes/_dashboard/admins/$adminId/delete.tsx b/dashboard/src/routes/_dashboard/admins/$adminId/delete.tsx index c03b955..dfb9609 100644 --- a/dashboard/src/routes/_dashboard/admins/$adminId/delete.tsx +++ b/dashboard/src/routes/_dashboard/admins/$adminId/delete.tsx @@ -5,7 +5,7 @@ import { import { AdminsDeleteConfirmationDialog, useRouterAdminContext, -} from "@marzneshin/features/admins"; +} from "@marzneshin/modules/admins"; import { useDialog } from "@marzneshin/hooks"; const AdminDelete = () => { diff --git a/dashboard/src/routes/_dashboard/admins/$adminId/edit.tsx b/dashboard/src/routes/_dashboard/admins/$adminId/edit.tsx index ff0347a..65886df 100644 --- a/dashboard/src/routes/_dashboard/admins/$adminId/edit.tsx +++ b/dashboard/src/routes/_dashboard/admins/$adminId/edit.tsx @@ -5,7 +5,7 @@ import { import { AdminsMutationDialog, useRouterAdminContext, -} from "@marzneshin/features/admins"; +} from "@marzneshin/modules/admins"; const AdminEdit = () => { const value = useRouterAdminContext() diff --git a/dashboard/src/routes/_dashboard/admins/$adminId/index.tsx b/dashboard/src/routes/_dashboard/admins/$adminId/index.tsx index f1a750f..30efdf7 100644 --- a/dashboard/src/routes/_dashboard/admins/$adminId/index.tsx +++ b/dashboard/src/routes/_dashboard/admins/$adminId/index.tsx @@ -5,7 +5,7 @@ import { import { useRouterAdminContext, AdminsSettingsDialog, -} from "@marzneshin/features/admins"; +} from "@marzneshin/modules/admins"; import { useDialog } from "@marzneshin/hooks"; const AdminOpen = () => { diff --git a/dashboard/src/routes/_dashboard/admins/create.tsx b/dashboard/src/routes/_dashboard/admins/create.tsx index 63adfb2..4d39cb3 100644 --- a/dashboard/src/routes/_dashboard/admins/create.tsx +++ b/dashboard/src/routes/_dashboard/admins/create.tsx @@ -1,5 +1,5 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router"; -import { AdminsMutationDialog } from "@marzneshin/features/admins"; +import { AdminsMutationDialog } from "@marzneshin/modules/admins"; const AdminCreate = () => { const navigate = useNavigate({ from: "/admins/create" }); diff --git a/package.json b/package.json deleted file mode 100644 index 33c4fee..0000000 --- a/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "yaml": "^2.5.0" - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index fc98ac4..0000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,24 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - yaml: - specifier: ^2.5.0 - version: 2.5.0 - -packages: - - yaml@2.5.0: - resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} - engines: {node: '>= 14'} - hasBin: true - -snapshots: - - yaml@2.5.0: {}