Add per-user saved column visibility for tables
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -37,6 +37,7 @@ import { PlatformModule } from './platform/platform.module';
|
||||
import { BillingModule } from './billing/billing.module';
|
||||
import { AuditLogsModule } from './audit-logs/audit-logs.module';
|
||||
import { SavedViewsModule } from './saved-views/saved-views.module';
|
||||
import { TablePrefsModule } from './table-prefs/table-prefs.module';
|
||||
import { PublicApiModule } from './public-api/public-api.module';
|
||||
import { SmsCampaignsModule } from './sms-campaigns/sms-campaigns.module';
|
||||
import { TeamsModule } from './teams/teams.module';
|
||||
@@ -89,6 +90,7 @@ import { ConversationsModule } from './conversations/conversations.module';
|
||||
TahesabModule,
|
||||
AuditLogsModule,
|
||||
SavedViewsModule,
|
||||
TablePrefsModule,
|
||||
PublicApiModule,
|
||||
SmsCampaignsModule,
|
||||
TrackingModule,
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
Put,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
ArrayMaxSize,
|
||||
IsArray,
|
||||
IsString,
|
||||
Matches,
|
||||
MaxLength,
|
||||
} from 'class-validator';
|
||||
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
||||
import { CurrentUser } from '../auth/current-user.decorator';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
|
||||
const TABLE_KEY_RE = /^[a-z0-9_.-]{1,80}$/i;
|
||||
|
||||
class SaveTablePrefDto {
|
||||
@IsArray()
|
||||
@ArrayMaxSize(80)
|
||||
@IsString({ each: true })
|
||||
@MaxLength(80, { each: true })
|
||||
hiddenColumns!: string[];
|
||||
}
|
||||
|
||||
class TableKeyParam {
|
||||
@Matches(TABLE_KEY_RE)
|
||||
key!: string;
|
||||
}
|
||||
|
||||
type Actor = { userId: string; organizationId: string };
|
||||
|
||||
@Controller('table-prefs')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
export class TablePrefsController {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
@Get()
|
||||
async list(@CurrentUser() user: Actor) {
|
||||
const rows = await this.prisma.userTablePreference.findMany({
|
||||
where: { userId: user.userId, organizationId: user.organizationId },
|
||||
select: { tableKey: true, hiddenColumns: true },
|
||||
});
|
||||
const out: Record<string, string[]> = {};
|
||||
for (const row of rows) out[row.tableKey] = row.hiddenColumns;
|
||||
return out;
|
||||
}
|
||||
|
||||
@Put(':key')
|
||||
async save(
|
||||
@CurrentUser() user: Actor,
|
||||
@Param() params: TableKeyParam,
|
||||
@Body() dto: SaveTablePrefDto,
|
||||
) {
|
||||
const hiddenColumns = [...new Set(dto.hiddenColumns.map((c) => c.trim()).filter(Boolean))];
|
||||
const row = await this.prisma.userTablePreference.upsert({
|
||||
where: {
|
||||
userId_organizationId_tableKey: {
|
||||
userId: user.userId,
|
||||
organizationId: user.organizationId,
|
||||
tableKey: params.key,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
userId: user.userId,
|
||||
organizationId: user.organizationId,
|
||||
tableKey: params.key,
|
||||
hiddenColumns,
|
||||
},
|
||||
update: { hiddenColumns },
|
||||
select: { tableKey: true, hiddenColumns: true },
|
||||
});
|
||||
return row;
|
||||
}
|
||||
|
||||
@Delete(':key')
|
||||
async reset(@CurrentUser() user: Actor, @Param() params: TableKeyParam) {
|
||||
await this.prisma.userTablePreference.deleteMany({
|
||||
where: {
|
||||
userId: user.userId,
|
||||
organizationId: user.organizationId,
|
||||
tableKey: params.key,
|
||||
},
|
||||
});
|
||||
return { ok: true };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AuthModule } from '../auth/auth.module';
|
||||
import { TablePrefsController } from './table-prefs.controller';
|
||||
|
||||
@Module({
|
||||
imports: [AuthModule],
|
||||
controllers: [TablePrefsController],
|
||||
})
|
||||
export class TablePrefsModule {}
|
||||
Reference in New Issue
Block a user