Задать вопрос
@linoa123

React Admin Nest JS Next JS в чем ошибка?

The Content-Range header is missing in the HTTP Response. The simple REST data provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare Content-Range in the Access-Control-Expose-Headers header?


import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
import * as cookieParser from 'cookie-parser';
import * as express from 'express';
import { join } from 'path';

async function bootstrap() {
	const app = await NestFactory.create(AppModule);

	app.use(cookieParser()); 
	app.setGlobalPrefix('api')
	app.enableCors({
		origin: [process.env.CLIENT_URL], 
		credentials: true,
		exposedHeaders: ['set-cookie'],
	});

	app.use('/uploads', express.static(join(__dirname, '..', 'uploads')));

	const config = new DocumentBuilder()
		.setTitle('example')
		.setDescription('Тесты api проекта')
		.setVersion('1.0')
		.build();
	const document = SwaggerModule.createDocument(app, config);
	SwaggerModule.setup('docs', app, document);

	await app.listen(process.env.PORT! || 4200);
}

bootstrap();


import { Controller, Get, Post, Put, Delete, Body, Param } from '@nestjs/common';
import { TestsService } from './tests.service';

@Controller('tests')
export class TestsController {
    constructor(private readonly testsService: TestsService) {}

    @Get()
    async getList() {
        return this.testsService.findAll();
    }

    @Get(':id')
    async getOne(@Param('id') id: string) {
        return this.testsService.findOne(id);
    }

    @Post()
    async create(@Body() createDTO: any) {
        return this.testsService.create(createDTO);
    }

    @Put(':id')
    async update(@Param('id') id: string, @Body() updateDTO: any) {
        return this.testsService.update(id, updateDTO);
    }

    @Delete(':id')
    async delete(@Param('id') id: string) {
        return this.testsService.delete(id);
    }
}








import { Injectable } from '@nestjs/common';

@Injectable()
export class TestsService {
    private tests = []; // Example in-memory storage

    findAll() {
        return this.tests; // Fetch all tests
    }

    findOne(id: string) {
        return this.tests.find(test => test.id === id); // Find a specific test
    }

    create(createDTO: any) {
        const newTest = { id: Date.now().toString(), ...createDTO };
        this.tests.push(newTest);
        return newTest; // Create a new test
    }

    update(id: string, updateDTO: any) {
        const testIndex = this.tests.findIndex(test => test.id === id);
        if (testIndex > -1) {
            this.tests[testIndex] = { ...this.tests[testIndex], ...updateDTO };
            return this.tests[testIndex]; // Update an existing test
        }
    }

    delete(id: string) {
        this.tests = this.tests.filter(test => test.id !== id); // Delete a test
        return { deleted: true }; // Return deletion confirmation
    }
}


'use client';
import simpleRestProvider from 'ra-data-simple-rest';
import {
	Admin,
	Resource,
	List,
	Create,
	Edit,
	Show,
	SimpleList,
	SimpleForm,
	TextInput,
	Datagrid,
	TextField,
	EditButton,
	DeleteButton,
	ShowButton,
} from 'react-admin';
import { useUserStore } from '@/store/use-user-store';
import { redirect } from 'next/navigation';

const dataProvider = simpleRestProvider(
	`${process.env.NEXT_PUBLIC_SERVER_URL}/api`
);

const AdminsPage = () => {
	const { user, isLoading: isUserLoading } = useUserStore();
	if (isUserLoading) return null;
	if (!user?.isAdmin) return redirect('/');

	return (
		<Admin dataProvider={dataProvider}>
			<Resource
				name='tests'
				list={TestList}
				create={TestCreate}
				edit={TestEdit}
				show={TestShow}
			/>
		</Admin>
	);
};

const TestList = props => (
	<List {...props}>
		<Datagrid>
			<TextField source='id' />
			<TextField source='title' />
			<TextField source='author' />
			<EditButton />
			<DeleteButton />
			<ShowButton />
		</Datagrid>
	</List>
);

const TestCreate = props => (
	<Create {...props}>
		<SimpleForm>
			<TextInput source='title' />
			<TextInput source='author' />
		</SimpleForm>
	</Create>
);

const TestEdit = props => (
	<Edit {...props}>
		<SimpleForm>
			<TextInput source='title' />
			<TextInput source='author' />
		</SimpleForm>
	</Edit>
);

const TestShow = props => (
	<Show {...props}>
		<SimpleList
			primaryText={record => record.title}
			secondaryText={record => record.author}
		/>
	</Show>
);

export default AdminsPage;
  • Вопрос задан
  • 65 просмотров
Подписаться 1 Простой 7 комментариев
Решения вопроса 1
yarkov
@yarkov
Помог ответ? Отметь решением.
Выглядеть будет ПРИМЕРНО так навскидку

Смотри только если сам не смог сделать

import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';

import { Response as ExpressResponse } from 'express';

@Injectable()
export class ResponseAddContentRangeToHeaderInterceptor implements NestInterceptor {
    intercept(context:ExecutionContext, next:CallHandler): Observable<any> {

        const ResponseObj:ExpressResponse = context.switchToHttp().getResponse();
        ResponseObj.setHeader('Access-Control-Expose-Headers', 'Content-Range' );
        return next.handle();
    }
}


async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    app.useGlobalInterceptors(new ResponseAddContentRangeToHeaderInterceptor());
    await app.listen(8080);
}

Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы