diff --git a/package.json b/package.json index bdeea5211..5cb521650 100644 --- a/package.json +++ b/package.json @@ -150,6 +150,7 @@ "svg-url-loader": "^7.1.1", "tailwindcss": "^3.0.23", "terser-webpack-plugin": "^4.2.3", + "ts-essentials": "^9.1.2", "twin.macro": "^2.8.2", "typescript": "^4.4.4", "webpack": "^4.46.0", diff --git a/resources/scripts/api/admin/egg.ts b/resources/scripts/api/admin/egg.ts index 4fd5e7844..357f8e544 100644 --- a/resources/scripts/api/admin/egg.ts +++ b/resources/scripts/api/admin/egg.ts @@ -1,7 +1,7 @@ import { Model, UUID, WithRelationships, withRelationships } from '@/api/admin/index'; import { Nest } from '@/api/admin/nest'; import http, { QueryBuilderParams, withQueryBuilderParams } from '@/api/http'; -import { AdminTransformers } from '@/api/admin/transformers'; +import Transformers from '@definitions/admin/transformers'; import { AxiosError } from 'axios'; import { useRouteMatch } from 'react-router-dom'; import useSWR, { SWRResponse } from 'swr'; @@ -64,7 +64,7 @@ export const getEgg = async (id: number | string): Promise => { }, }); - return withRelationships(AdminTransformers.toEgg(data), 'nest', 'variables'); + return withRelationships(Transformers.toEgg(data), 'nest', 'variables'); }; export const searchEggs = async (nestId: number, params: QueryBuilderParams<'name'>): Promise[]> => { @@ -75,7 +75,7 @@ export const searchEggs = async (nestId: number, params: QueryBuilderParams<'nam }, }); - return data.data.map(AdminTransformers.toEgg); + return data.data.map(Transformers.toEgg); }; export const exportEgg = async (eggId: number): Promise> => { diff --git a/resources/scripts/api/admin/eggs/createEggVariable.ts b/resources/scripts/api/admin/eggs/createEggVariable.ts index 72f2c314d..1fbd9ada2 100644 --- a/resources/scripts/api/admin/eggs/createEggVariable.ts +++ b/resources/scripts/api/admin/eggs/createEggVariable.ts @@ -1,6 +1,6 @@ import http from '@/api/http'; import { EggVariable } from '@/api/admin/egg'; -import { AdminTransformers } from '@/api/admin/transformers'; +import Transformers from '@definitions/admin/transformers'; export type CreateEggVariable = Omit; @@ -18,5 +18,5 @@ export default async (eggId: number, variable: CreateEggVariable): Promise[]): Promise => { const { data } = await http.patch( @@ -17,5 +17,5 @@ export default async (eggId: number, variables: Omit): Promise): Promise => { @@ -72,7 +72,7 @@ export const searchNodes = async (params: QueryBuilderParams<'name'>): Promise): Promise => { @@ -80,5 +80,5 @@ export const getAllocations = async (id: string | number, params?: QueryBuilderP params: withQueryBuilderParams(params), }); - return data.data.map(AdminTransformers.toAllocation); + return data.data.map(Transformers.toAllocation); }; diff --git a/resources/scripts/api/admin/server.ts b/resources/scripts/api/admin/server.ts index f32a4fa59..ef62c67af 100644 --- a/resources/scripts/api/admin/server.ts +++ b/resources/scripts/api/admin/server.ts @@ -3,9 +3,9 @@ import { AxiosError } from 'axios'; import { useRouteMatch } from 'react-router-dom'; import http from '@/api/http'; import { Model, UUID, withRelationships, WithRelationships } from '@/api/admin/index'; -import { AdminTransformers } from '@/api/admin/transformers'; +import Transformers from '@definitions/admin/transformers'; import { Allocation, Node } from '@/api/admin/node'; -import { User } from '@/api/admin/user'; +import { User } from '@definitions/admin/models'; import { Egg, EggVariable } from '@/api/admin/egg'; import { Nest } from '@/api/admin/nest'; @@ -83,7 +83,7 @@ export const getServer = async (id: number | string): Promise => { }, }); - return withRelationships(AdminTransformers.toServer(data), 'allocations', 'user', 'node', 'variables'); + return withRelationships(Transformers.toServer(data), 'allocations', 'user', 'node', 'variables'); }; /** diff --git a/resources/scripts/api/admin/transformers.ts b/resources/scripts/api/admin/transformers.ts deleted file mode 100644 index bed54fb8f..000000000 --- a/resources/scripts/api/admin/transformers.ts +++ /dev/null @@ -1,212 +0,0 @@ -/* eslint-disable camelcase */ -import { Allocation, Node } from '@/api/admin/node'; -import { Server, ServerVariable } from '@/api/admin/server'; -import { FractalResponseData, FractalResponseList } from '@/api/http'; -import { User, UserRole } from '@/api/admin/user'; -import { Location } from '@/api/admin/location'; -import { Egg, EggVariable } from '@/api/admin/egg'; -import { Nest } from '@/api/admin/nest'; - -const isList = (data: FractalResponseList | FractalResponseData): data is FractalResponseList => data.object === 'list'; - -function transform (data: undefined, transformer: (callback: FractalResponseData) => T, missing?: M): undefined; -function transform (data: FractalResponseData | undefined, transformer: (callback: FractalResponseData) => T, missing?: M): T | M | undefined; -function transform (data: FractalResponseList | undefined, transformer: (callback: FractalResponseData) => T, missing?: M): T[] | undefined; -function transform (data: FractalResponseData | FractalResponseList | undefined, transformer: (callback: FractalResponseData) => T, missing = undefined) { - if (data === undefined) return undefined; - - if (isList(data)) { - return data.data.map(transformer); - } - - return !data ? missing : transformer(data); -} - -export class AdminTransformers { - static toServer = ({ attributes }: FractalResponseData): Server => { - const { oom_disabled, ...limits } = attributes.limits; - const { allocations, egg, nest, node, user, variables } = attributes.relationships || {}; - - return { - id: attributes.id, - uuid: attributes.uuid, - externalId: attributes.external_id, - identifier: attributes.identifier, - name: attributes.name, - description: attributes.description, - status: attributes.status, - userId: attributes.owner_id, - nodeId: attributes.node_id, - allocationId: attributes.allocation_id, - eggId: attributes.egg_id, - nestId: attributes.nest_id, - limits: { ...limits, oomDisabled: oom_disabled }, - featureLimits: attributes.feature_limits, - container: attributes.container, - createdAt: new Date(attributes.created_at), - updatedAt: new Date(attributes.updated_at), - relationships: { - allocations: transform(allocations as FractalResponseList | undefined, this.toAllocation), - nest: transform(nest as FractalResponseData | undefined, this.toNest), - egg: transform(egg as FractalResponseData | undefined, this.toEgg), - node: transform(node as FractalResponseData | undefined, this.toNode), - user: transform(user as FractalResponseData | undefined, this.toUser), - variables: transform(variables as FractalResponseList | undefined, this.toServerEggVariable), - }, - }; - }; - - static toNode = ({ attributes }: FractalResponseData): Node => { - return { - id: attributes.id, - uuid: attributes.uuid, - isPublic: attributes.public, - locationId: attributes.location_id, - databaseHostId: attributes.database_host_id, - name: attributes.name, - description: attributes.description, - fqdn: attributes.fqdn, - ports: { - http: { - public: attributes.publicPortHttp, - listen: attributes.listenPortHttp, - }, - sftp: { - public: attributes.publicPortSftp, - listen: attributes.listenPortSftp, - }, - }, - scheme: attributes.scheme, - isBehindProxy: attributes.behindProxy, - isMaintenanceMode: attributes.maintenance_mode, - memory: attributes.memory, - memoryOverallocate: attributes.memory_overallocate, - disk: attributes.disk, - diskOverallocate: attributes.disk_overallocate, - uploadSize: attributes.upload_size, - daemonBase: attributes.daemonBase, - createdAt: new Date(attributes.created_at), - updatedAt: new Date(attributes.updated_at), - relationships: { - location: transform(attributes.relationships?.location as FractalResponseData, this.toLocation), - }, - }; - }; - - static toUserRole = ({ attributes }: FractalResponseData): UserRole => ({ - id: attributes.id, - name: attributes.name, - description: attributes.description, - relationships: {}, - }); - - static toUser = ({ attributes }: FractalResponseData): User => { - return { - id: attributes.id, - uuid: attributes.uuid, - externalId: attributes.external_id, - username: attributes.username, - email: attributes.email, - language: attributes.language, - adminRoleId: attributes.adminRoleId || null, - roleName: attributes.role_name, - isRootAdmin: attributes.root_admin, - isUsingTwoFactor: attributes['2fa'] || false, - avatarUrl: attributes.avatar_url, - createdAt: new Date(attributes.created_at), - updatedAt: new Date(attributes.updated_at), - relationships: { - role: transform(attributes.relationships?.role as FractalResponseData, this.toUserRole) || null, - }, - }; - }; - - static toLocation = ({ attributes }: FractalResponseData): Location => ({ - id: attributes.id, - short: attributes.short, - long: attributes.long, - createdAt: new Date(attributes.created_at), - updatedAt: new Date(attributes.updated_at), - relationships: { - nodes: transform(attributes.relationships?.node as FractalResponseList, this.toNode), - }, - }); - - static toEgg = ({ attributes }: FractalResponseData): Egg => ({ - id: attributes.id, - uuid: attributes.uuid, - nestId: attributes.nest_id, - author: attributes.author, - name: attributes.name, - description: attributes.description, - features: attributes.features, - dockerImages: attributes.docker_images, - configFiles: attributes.config?.files, - configStartup: attributes.config?.startup, - configStop: attributes.config?.stop, - configFrom: attributes.config?.extends, - startup: attributes.startup, - copyScriptFrom: attributes.copy_script_from, - scriptContainer: attributes.script?.container, - scriptEntry: attributes.script?.entry, - scriptIsPrivileged: attributes.script?.privileged, - scriptInstall: attributes.script?.install, - createdAt: new Date(attributes.created_at), - updatedAt: new Date(attributes.updated_at), - relationships: { - nest: transform(attributes.relationships?.nest as FractalResponseData, this.toNest), - variables: transform(attributes.relationships?.variables as FractalResponseList, this.toEggVariable), - }, - }); - - static toEggVariable = ({ attributes }: FractalResponseData): EggVariable => ({ - id: attributes.id, - eggId: attributes.egg_id, - name: attributes.name, - description: attributes.description, - environmentVariable: attributes.env_variable, - defaultValue: attributes.default_value, - isUserViewable: attributes.user_viewable, - isUserEditable: attributes.user_editable, - // isRequired: attributes.required, - rules: attributes.rules, - createdAt: new Date(attributes.created_at), - updatedAt: new Date(attributes.updated_at), - relationships: {}, - }); - - static toServerEggVariable = (data: FractalResponseData): ServerVariable => ({ - ...this.toEggVariable(data), - serverValue: data.attributes.server_value, - }); - - static toAllocation = ({ attributes }: FractalResponseData): Allocation => ({ - id: attributes.id, - ip: attributes.ip, - port: attributes.port, - alias: attributes.alias || null, - isAssigned: attributes.assigned, - relationships: { - node: transform(attributes.relationships?.node as FractalResponseData, this.toNode), - server: transform(attributes.relationships?.server as FractalResponseData, this.toServer), - }, - getDisplayText (): string { - const raw = `${this.ip}:${this.port}`; - - return !this.alias ? raw : `${this.alias} (${raw})`; - }, - }); - - static toNest = ({ attributes }: FractalResponseData): Nest => ({ - id: attributes.id, - uuid: attributes.uuid, - author: attributes.author, - name: attributes.name, - description: attributes.description, - createdAt: new Date(attributes.created_at), - updatedAt: new Date(attributes.updated_at), - relationships: { - eggs: transform(attributes.relationships?.eggs as FractalResponseList, this.toEgg), - }, - }); -} diff --git a/resources/scripts/api/admin/user.ts b/resources/scripts/api/admin/user.ts index b92315208..1b1de004f 100644 --- a/resources/scripts/api/admin/user.ts +++ b/resources/scripts/api/admin/user.ts @@ -1,38 +1,11 @@ -import { Model, UUID } from '@/api/admin/index'; -import { Server } from '@/api/admin/server'; import http, { QueryBuilderParams, withQueryBuilderParams } from '@/api/http'; -import { AdminTransformers } from '@/api/admin/transformers'; - -export interface User extends Model { - id: number; - uuid: UUID; - externalId: string; - username: string; - email: string; - language: string; - adminRoleId: number | null; - roleName: string; - isRootAdmin: boolean; - isUsingTwoFactor: boolean; - avatarUrl: string; - createdAt: Date; - updatedAt: Date; - relationships: { - role: UserRole | null; - servers?: Server[]; - }; -} - -export interface UserRole extends Model { - id: string; - name: string; - description: string; -} +import Transformers from '@definitions/admin/transformers'; +import { User } from '@definitions/admin/models'; export const getUser = async (id: string | number): Promise => { const { data } = await http.get(`/api/application/users/${id}`); - return AdminTransformers.toUser(data.data); + return Transformers.toUser(data.data); }; export const searchUserAccounts = async (params: QueryBuilderParams<'username' | 'email'>): Promise => { @@ -40,5 +13,5 @@ export const searchUserAccounts = async (params: QueryBuilderParams<'username' | params: withQueryBuilderParams(params), }); - return data.data.map(AdminTransformers.toUser); + return data.data.map(Transformers.toUser); }; diff --git a/resources/scripts/api/definitions/admin/models.d.ts b/resources/scripts/api/definitions/admin/models.d.ts index e69de29bb..50c74fdef 100644 --- a/resources/scripts/api/definitions/admin/models.d.ts +++ b/resources/scripts/api/definitions/admin/models.d.ts @@ -0,0 +1,48 @@ +import { Model as BaseModel, UUID } from '@/api/definitions'; +import { Server } from '@/api/admin/server'; +import { MarkRequired } from 'ts-essentials'; + +interface Model extends BaseModel { + relationships: Record; +} + +/** + * Allows a model to have optional relationships that are marked as being + * present in a given pathway. This allows different API calls to specify the + * "completeness" of a response object without having to make every API return + * the same information, or every piece of logic do explicit null checking. + * + * Example: + * >> const user: WithLoadedRelations = {}; + * >> // "user.servers" is no longer potentially undefined. + */ +type WithLoadedRelations = M & { + relationships: MarkRequired; +}; + +interface User extends Model { + id: number; + uuid: UUID; + externalId: string; + username: string; + email: string; + language: string; + adminRoleId: number | null; + roleName: string; + isRootAdmin: boolean; + isUsingTwoFactor: boolean; + avatarUrl: string; + createdAt: Date; + updatedAt: Date; + relationships: { + role: UserRole | null; + // TODO: just use an API call, this is probably a bad idea for performance. + servers?: Server[]; + }; +} + +interface UserRole extends Model { + id: string; + name: string; + description: string; +} diff --git a/resources/scripts/api/definitions/admin/transformers.ts b/resources/scripts/api/definitions/admin/transformers.ts index e69de29bb..07095ab07 100644 --- a/resources/scripts/api/definitions/admin/transformers.ts +++ b/resources/scripts/api/definitions/admin/transformers.ts @@ -0,0 +1,212 @@ +/* eslint-disable camelcase */ +import { Allocation, Node } from '@/api/admin/node'; +import { Server, ServerVariable } from '@/api/admin/server'; +import { FractalResponseData, FractalResponseList } from '@/api/http'; +import * as Models from '@definitions/admin/models'; +import { Location } from '@/api/admin/location'; +import { Egg, EggVariable } from '@/api/admin/egg'; +import { Nest } from '@/api/admin/nest'; + +const isList = (data: FractalResponseList | FractalResponseData): data is FractalResponseList => data.object === 'list'; + +function transform (data: undefined, transformer: (callback: FractalResponseData) => T, missing?: M): undefined; +function transform (data: FractalResponseData | undefined, transformer: (callback: FractalResponseData) => T, missing?: M): T | M | undefined; +function transform (data: FractalResponseList | undefined, transformer: (callback: FractalResponseData) => T, missing?: M): T[] | undefined; +function transform (data: FractalResponseData | FractalResponseList | undefined, transformer: (callback: FractalResponseData) => T, missing = undefined) { + if (data === undefined) return undefined; + + if (isList(data)) { + return data.data.map(transformer); + } + + return !data ? missing : transformer(data); +} + +export default class Transformers { + static toServer = ({ attributes }: FractalResponseData): Server => { + const { oom_disabled, ...limits } = attributes.limits; + const { allocations, egg, nest, node, user, variables } = attributes.relationships || {}; + + return { + id: attributes.id, + uuid: attributes.uuid, + externalId: attributes.external_id, + identifier: attributes.identifier, + name: attributes.name, + description: attributes.description, + status: attributes.status, + userId: attributes.owner_id, + nodeId: attributes.node_id, + allocationId: attributes.allocation_id, + eggId: attributes.egg_id, + nestId: attributes.nest_id, + limits: { ...limits, oomDisabled: oom_disabled }, + featureLimits: attributes.feature_limits, + container: attributes.container, + createdAt: new Date(attributes.created_at), + updatedAt: new Date(attributes.updated_at), + relationships: { + allocations: transform(allocations as FractalResponseList | undefined, this.toAllocation), + nest: transform(nest as FractalResponseData | undefined, this.toNest), + egg: transform(egg as FractalResponseData | undefined, this.toEgg), + node: transform(node as FractalResponseData | undefined, this.toNode), + user: transform(user as FractalResponseData | undefined, this.toUser), + variables: transform(variables as FractalResponseList | undefined, this.toServerEggVariable), + }, + }; + }; + + static toNode = ({ attributes }: FractalResponseData): Node => { + return { + id: attributes.id, + uuid: attributes.uuid, + isPublic: attributes.public, + locationId: attributes.location_id, + databaseHostId: attributes.database_host_id, + name: attributes.name, + description: attributes.description, + fqdn: attributes.fqdn, + ports: { + http: { + public: attributes.publicPortHttp, + listen: attributes.listenPortHttp, + }, + sftp: { + public: attributes.publicPortSftp, + listen: attributes.listenPortSftp, + }, + }, + scheme: attributes.scheme, + isBehindProxy: attributes.behindProxy, + isMaintenanceMode: attributes.maintenance_mode, + memory: attributes.memory, + memoryOverallocate: attributes.memory_overallocate, + disk: attributes.disk, + diskOverallocate: attributes.disk_overallocate, + uploadSize: attributes.upload_size, + daemonBase: attributes.daemonBase, + createdAt: new Date(attributes.created_at), + updatedAt: new Date(attributes.updated_at), + relationships: { + location: transform(attributes.relationships?.location as FractalResponseData, this.toLocation), + }, + }; + }; + + static toUserRole = ({ attributes }: FractalResponseData): Models.UserRole => ({ + id: attributes.id, + name: attributes.name, + description: attributes.description, + relationships: {}, + }); + + static toUser = ({ attributes }: FractalResponseData): Models.User => { + return { + id: attributes.id, + uuid: attributes.uuid, + externalId: attributes.external_id, + username: attributes.username, + email: attributes.email, + language: attributes.language, + adminRoleId: attributes.adminRoleId || null, + roleName: attributes.role_name, + isRootAdmin: attributes.root_admin, + isUsingTwoFactor: attributes['2fa'] || false, + avatarUrl: attributes.avatar_url, + createdAt: new Date(attributes.created_at), + updatedAt: new Date(attributes.updated_at), + relationships: { + role: transform(attributes.relationships?.role as FractalResponseData, this.toUserRole) || null, + }, + }; + }; + + static toLocation = ({ attributes }: FractalResponseData): Location => ({ + id: attributes.id, + short: attributes.short, + long: attributes.long, + createdAt: new Date(attributes.created_at), + updatedAt: new Date(attributes.updated_at), + relationships: { + nodes: transform(attributes.relationships?.node as FractalResponseList, this.toNode), + }, + }); + + static toEgg = ({ attributes }: FractalResponseData): Egg => ({ + id: attributes.id, + uuid: attributes.uuid, + nestId: attributes.nest_id, + author: attributes.author, + name: attributes.name, + description: attributes.description, + features: attributes.features, + dockerImages: attributes.docker_images, + configFiles: attributes.config?.files, + configStartup: attributes.config?.startup, + configStop: attributes.config?.stop, + configFrom: attributes.config?.extends, + startup: attributes.startup, + copyScriptFrom: attributes.copy_script_from, + scriptContainer: attributes.script?.container, + scriptEntry: attributes.script?.entry, + scriptIsPrivileged: attributes.script?.privileged, + scriptInstall: attributes.script?.install, + createdAt: new Date(attributes.created_at), + updatedAt: new Date(attributes.updated_at), + relationships: { + nest: transform(attributes.relationships?.nest as FractalResponseData, this.toNest), + variables: transform(attributes.relationships?.variables as FractalResponseList, this.toEggVariable), + }, + }); + + static toEggVariable = ({ attributes }: FractalResponseData): EggVariable => ({ + id: attributes.id, + eggId: attributes.egg_id, + name: attributes.name, + description: attributes.description, + environmentVariable: attributes.env_variable, + defaultValue: attributes.default_value, + isUserViewable: attributes.user_viewable, + isUserEditable: attributes.user_editable, + // isRequired: attributes.required, + rules: attributes.rules, + createdAt: new Date(attributes.created_at), + updatedAt: new Date(attributes.updated_at), + relationships: {}, + }); + + static toServerEggVariable = (data: FractalResponseData): ServerVariable => ({ + ...this.toEggVariable(data), + serverValue: data.attributes.server_value, + }); + + static toAllocation = ({ attributes }: FractalResponseData): Allocation => ({ + id: attributes.id, + ip: attributes.ip, + port: attributes.port, + alias: attributes.alias || null, + isAssigned: attributes.assigned, + relationships: { + node: transform(attributes.relationships?.node as FractalResponseData, this.toNode), + server: transform(attributes.relationships?.server as FractalResponseData, this.toServer), + }, + getDisplayText (): string { + const raw = `${this.ip}:${this.port}`; + + return !this.alias ? raw : `${this.alias} (${raw})`; + }, + }); + + static toNest = ({ attributes }: FractalResponseData): Nest => ({ + id: attributes.id, + uuid: attributes.uuid, + author: attributes.author, + name: attributes.name, + description: attributes.description, + createdAt: new Date(attributes.created_at), + updatedAt: new Date(attributes.updated_at), + relationships: { + eggs: transform(attributes.relationships?.eggs as FractalResponseList, this.toEgg), + }, + }); +} diff --git a/resources/scripts/api/definitions/index.d.ts b/resources/scripts/api/definitions/index.d.ts new file mode 100644 index 000000000..7c43963dd --- /dev/null +++ b/resources/scripts/api/definitions/index.d.ts @@ -0,0 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface Model {} + +export type UUID = string; diff --git a/resources/scripts/api/definitions/user/models.d.ts b/resources/scripts/api/definitions/user/models.d.ts index e587d70de..22b9ce281 100644 --- a/resources/scripts/api/definitions/user/models.d.ts +++ b/resources/scripts/api/definitions/user/models.d.ts @@ -1,8 +1,7 @@ -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface Model {} +import { Model, UUID } from '@/api/definitions'; interface SecurityKey extends Model { - uuid: string; + uuid: UUID; name: string; type: 'public-key'; publicKeyId: string; diff --git a/resources/scripts/components/admin/servers/OwnerSelect.tsx b/resources/scripts/components/admin/servers/OwnerSelect.tsx index e97f3b0b2..8cc8a1647 100644 --- a/resources/scripts/components/admin/servers/OwnerSelect.tsx +++ b/resources/scripts/components/admin/servers/OwnerSelect.tsx @@ -1,7 +1,8 @@ import React, { useState } from 'react'; import { useFormikContext } from 'formik'; import SearchableSelect, { Option } from '@/components/elements/SearchableSelect'; -import { User, searchUserAccounts } from '@/api/admin/user'; +import { User } from '@definitions/admin/models'; +import { searchUserAccounts } from '@/api/admin/user'; export default ({ selected }: { selected?: User }) => { const { setFieldValue } = useFormikContext(); diff --git a/resources/scripts/components/admin/users/UserTableRow.tsx b/resources/scripts/components/admin/users/UserTableRow.tsx index 62d036a5c..10c87a48a 100644 --- a/resources/scripts/components/admin/users/UserTableRow.tsx +++ b/resources/scripts/components/admin/users/UserTableRow.tsx @@ -2,7 +2,7 @@ import { Checkbox } from '@/components/elements/inputs'; import { Dropdown } from '@/components/elements/dropdown'; import { BanIcon, DotsVerticalIcon, LockOpenIcon, PencilIcon, SupportIcon, TrashIcon } from '@heroicons/react/solid'; import React, { useState } from 'react'; -import { User } from '@/api/admin/user'; +import { User } from '@definitions/admin/models'; import { Dialog } from '@/components/elements/dialog'; import { Button } from '@/components/elements/button/index'; diff --git a/resources/scripts/components/admin/users/UsersContainerV2.tsx b/resources/scripts/components/admin/users/UsersContainerV2.tsx index f037fc9df..f5c9b4b37 100644 --- a/resources/scripts/components/admin/users/UsersContainerV2.tsx +++ b/resources/scripts/components/admin/users/UsersContainerV2.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import http from '@/api/http'; -import { User } from '@/api/admin/user'; -import { AdminTransformers } from '@/api/admin/transformers'; +import { User } from '@definitions/admin/models'; +import Transformers from '@definitions/admin/transformers'; import { LockOpenIcon, PlusIcon, SupportIcon, TrashIcon } from '@heroicons/react/solid'; import { Button } from '@/components/elements/button/index'; import { Checkbox, InputField } from '@/components/elements/inputs'; @@ -16,7 +16,7 @@ const UsersContainerV2 = () => { useEffect(() => { http.get('/api/application/users') .then(({ data }) => { - setUsers(data.data.map(AdminTransformers.toUser)); + setUsers(data.data.map(Transformers.toUser)); }) .catch(console.error); }, []); diff --git a/yarn.lock b/yarn.lock index d79ca6f68..0b0adb1ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11036,6 +11036,7 @@ fsevents@^1.2.7: swr: ^1.0.1 tailwindcss: ^3.0.23 terser-webpack-plugin: ^4.2.3 + ts-essentials: ^9.1.2 twin.macro: ^2.8.2 typescript: ^4.4.4 uuid: ^3.4.0 @@ -13389,6 +13390,15 @@ resolve@^2.0.0-next.3: languageName: node linkType: hard +"ts-essentials@npm:^9.1.2": + version: 9.1.2 + resolution: "ts-essentials@npm:9.1.2" + peerDependencies: + typescript: ">=4.1.0" + checksum: 3b14d8511557bd1bdec068505074ee41d3b1cdb052d3c66a5046f00b483bd4722d529b32a99cca424a9d7db9caff7ba108acbf344a5477a741e0616af5649b47 + languageName: node + linkType: hard + "ts-toolbelt@npm:^9.6.0": version: 9.6.0 resolution: "ts-toolbelt@npm:9.6.0"