Skip to content

Commit

Permalink
feat frozen columns (#589)
Browse files Browse the repository at this point in the history
  • Loading branch information
chavda-bhavik authored Jun 13, 2024
2 parents 1cd2e36 + 49e2a5d commit 8587e71
Show file tree
Hide file tree
Showing 26 changed files with 105 additions and 33 deletions.
8 changes: 6 additions & 2 deletions apps/api/src/app/column/commands/add-column.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ export class AddColumnCommand extends BaseCommand {

@IsBoolean()
@IsOptional()
isRequired = false;
isRequired? = false;

@IsBoolean()
@IsOptional()
isUnique = false;
isUnique? = false;

@IsBoolean()
@IsOptional()
isFrozen? = false;

@IsDefined()
type: ColumnTypesEnum;
Expand Down
8 changes: 6 additions & 2 deletions apps/api/src/app/column/commands/update-column.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ export class UpdateColumnCommand extends BaseCommand {

@IsBoolean()
@IsOptional()
isRequired = false;
isRequired? = false;

@IsBoolean()
@IsOptional()
isUnique = false;
isUnique? = false;

@IsBoolean()
@IsOptional()
isFrozen? = false;

@IsDefined()
type: ColumnTypesEnum;
Expand Down
11 changes: 9 additions & 2 deletions apps/api/src/app/column/dtos/column-request.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,21 @@ export class ColumnRequestDto {
})
@IsBoolean()
@IsOptional()
isRequired = false;
isRequired? = false;

@ApiPropertyOptional({
description: 'While true, it Indicates column value should be unique in data',
})
@IsBoolean()
@IsOptional()
isUnique = false;
isUnique? = false;

@ApiPropertyOptional({
description: 'While true, it Indicates column value should be frozen in data',
})
@IsBoolean()
@IsOptional()
isFrozen? = false;

@ApiProperty({
description: 'Specifies the type of column',
Expand Down
9 changes: 7 additions & 2 deletions apps/api/src/app/column/dtos/column-response.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ export class ColumnResponseDto {
@ApiPropertyOptional({
description: 'While true, it Indicates column value should exists in data',
})
isRequired = false;
isRequired? = false;

@ApiPropertyOptional({
description: 'While true, it Indicates column value should be unique in data',
})
isUnique = false;
isUnique? = false;

@ApiPropertyOptional({
description: 'While true, it Indicates column value should be frozen in data',
})
isFrozen? = false;

@ApiProperty({
description: 'Specifies the type of column',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export class CreateProject {
_templateId: template._id,
name: 'Date',
key: 'Date *',
isFrozen: true,
type: ColumnTypesEnum.DATE,
isRequired: true,
dateFormats: ['DD/MM/YYYY'],
Expand Down
4 changes: 4 additions & 0 deletions apps/api/src/app/shared/services/file/file.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ export class ExcelFileService {
worksheet.column(columnName).style('numberFormat', '@');
});

const frozenColumns = headings.filter((heading) => heading.isFrozen).length;
if (frozenColumns) worksheet.freezePanes(frozenColumns, 1); // freeze panes (freeze first n column and first row)
else worksheet.freezePanes(0, 1); // freeze 0 column and first row

headings.forEach((heading, index) => {
if (heading.type === ColumnTypesEnum.SELECT) {
const keyName = this.addSelectSheet(workbook, heading);
Expand Down
1 change: 1 addition & 0 deletions apps/api/src/app/shared/types/file.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ColumnTypesEnum } from '@impler/shared';
export interface IExcelFileHeading {
key: string;
isRequired?: boolean;
isFrozen?: boolean;
type: ColumnTypesEnum;
selectValues?: string[];
dateFormats?: string[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@ export class SaveSampleFile {
) {}

async execute(columns: ColumnEntity[], templateId: string) {
const columnKeys: IExcelFileHeading[] = columns.map((columnItem) => ({
key: columnItem.key,
type: columnItem.type as ColumnTypesEnum,
selectValues: columnItem.selectValues,
isRequired: columnItem.isRequired,
dateFormats: columnItem.dateFormats,
allowMultiSelect: columnItem.allowMultiSelect,
}));
const columnKeys: IExcelFileHeading[] = columns
.map((columnItem) => ({
key: columnItem.key,
type: columnItem.type as ColumnTypesEnum,
selectValues: columnItem.selectValues,
isFrozen: columnItem.isFrozen,
isRequired: columnItem.isRequired,
dateFormats: columnItem.dateFormats,
allowMultiSelect: columnItem.allowMultiSelect,
}))
.sort((a, b) => (a.isFrozen === b.isFrozen ? 0 : a.isFrozen ? -1 : 1));

const hasMultiSelect = columns.some(
(columnItem) => columnItem.type === ColumnTypesEnum.SELECT && columnItem.allowMultiSelect
);
Expand Down
1 change: 1 addition & 0 deletions apps/api/src/app/template/template.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ export class TemplateController {
alternateKeys: columnData.alternateKeys,
isRequired: columnData.isRequired,
isUnique: columnData.isUnique,
isFrozen: columnData.isFrozen,
name: columnData.name,
regex: columnData.regex,
regexDescription: columnData.regexDescription,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ export class GetTemplateColumns {
async execute(_templateId: string) {
return this.columnRepository.find(
{ _templateId },
'_id name key type alternateKeys isRequired isUnique selectValues regex dateFormats defaultValue sequence allowMultiSelect'
'_id name key type alternateKeys isRequired isUnique isFrozen selectValues regex dateFormats defaultValue sequence allowMultiSelect',
{
sort: {
isFrozen: -1,
},
}
);
}
}
4 changes: 2 additions & 2 deletions apps/api/src/app/upload/upload.controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars
import _whatever from 'multer';
import { Response } from 'express';
import { ColumnEntity, FileEntity } from '@impler/dal';
import { FileEntity } from '@impler/dal';
import { FileInterceptor } from '@nestjs/platform-express';
import { ACCESS_KEY_NAME, Defaults, UploadStatusEnum } from '@impler/shared';
import {
Expand Down Expand Up @@ -120,7 +120,7 @@ export class UploadController {
@ApiOperation({
summary: 'Get upload columns',
})
async getColumns(@Param('uploadId', ValidateMongoId) uploadId: string): Promise<ColumnEntity[]> {
async getColumns(@Param('uploadId', ValidateMongoId) uploadId: string) {
return this.getUploadColumns.execute(uploadId);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Injectable } from '@nestjs/common';
import { UploadRepository } from '@impler/dal';
import { ISchemaColumn } from '@impler/shared';

@Injectable()
export class GetUploadColumns {
constructor(private uploadRepository: UploadRepository) {}

async execute(_uploadId: string) {
const upload = await this.uploadRepository.findById(_uploadId, 'customSchema');
const columns = JSON.parse(upload.customSchema) as ISchemaColumn[];

return JSON.parse(upload.customSchema);
return columns.sort((a, b) => (a.isFrozen === b.isFrozen ? 0 : a.isFrozen ? -1 : 1));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class MakeUploadEntry {
{
_templateId: templateId,
},
'name key isRequired isUnique selectValues dateFormats defaultValue type regex sequence allowMultiSelect',
'name key isRequired isUnique isFrozen selectValues dateFormats defaultValue type regex sequence allowMultiSelect',
{
sort: 'sequence',
}
Expand All @@ -86,6 +86,7 @@ export class MakeUploadEntry {
formattedColumns[schemaItem.key] = {
name: schemaItem.name || 'Untitled Column',
isRequired: schemaItem.isRequired || false,
isFrozen: schemaItem.isFrozen,
key: schemaItem.key,
type: schemaItem.type || ColumnTypesEnum.STRING,
regex: schemaItem.regex,
Expand Down
1 change: 1 addition & 0 deletions apps/web/components/imports/forms/ColumnForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export function ColumnForm({ onSubmit, data, isLoading }: ColumnFormProps) {
) : (
<Checkbox label="Multi Select?" register={register('allowMultiSelect')} />
)}
<Checkbox label="Frozen?" register={register('isFrozen')} />
</Group>
<Button type="submit" fullWidth loading={isLoading}>
{data ? 'Update' : 'Add'}
Expand Down
19 changes: 14 additions & 5 deletions apps/web/components/imports/schema/ColumnsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,23 @@ export function ColumnsTable({ templateId }: ColumnsTableProps) {
width: '15%',
},
{
title: 'Is required?',
title: 'Required?',
key: 'isRequired',
width: '10%',
Cell: (item) => item.isRequired && <CheckIcon color={colors.success} />,
},
{
title: 'Is unique?',
title: 'Unique?',
key: 'isUnique',
width: '10%',
Cell: (item) => item.isUnique && <CheckIcon color={colors.success} />,
},
{
title: 'Frozen?',
key: 'isFrozen',
width: '10%',
Cell: (item) => item.isFrozen && <CheckIcon color={colors.success} />,
},
{
title: '',
key: 'actions',
Expand All @@ -101,7 +107,7 @@ export function ColumnsTable({ templateId }: ColumnsTableProps) {
<tr>
{showAddRow ? (
<>
<td colSpan={4} style={{ borderRight: 'none' }}>
<td colSpan={5} style={{ borderRight: 'none' }}>
<Flex gap="xs" align={'center'}>
<Input autoFocus required placeholder="Column Name" {...register('name')} />
<Input required placeholder="Column Key" {...register('key')} />
Expand Down Expand Up @@ -200,7 +206,10 @@ export function ColumnsTable({ templateId }: ColumnsTableProps) {
/>
) : null}
<Checkbox label="Required?" title="Required?" {...register('isRequired')} id="isRequired" />
<Checkbox label="Unique?" title="Unique?" {...register('isUnique')} id="isUnique" />
{typeValue !== 'Select' ? (
<Checkbox label="Unique?" title="Unique?" {...register('isUnique')} id="isUnique" />
) : null}
<Checkbox label="Frozen?" title="Frozen?" {...register('isFrozen')} id="isFrozen" />
</Flex>
</td>
<td style={{ borderLeft: 'none' }}>
Expand All @@ -215,7 +224,7 @@ export function ColumnsTable({ templateId }: ColumnsTableProps) {
</td>
</>
) : (
<td colSpan={5}>
<td colSpan={6}>
<Tooltip label="Add new column" withArrow position="top-start">
<ActionIcon
id="add-column"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const getInputStyles = (theme: MantineTheme, size: MantineSize): CSSObject => ({
content: 'attr(data-placeholder)',
pointerEvents: 'none',
display: 'block',
color: theme.colorScheme === 'dark' ? theme.colors.dark[2] : theme.colors.gray[5],
color: theme.colorScheme === 'dark' ? theme.colors.dark[3] : theme.colors.gray[5],
},
});
const getSelectItemStyles = (theme: MantineTheme, size: MantineSize): CSSObject => ({
Expand Down
4 changes: 2 additions & 2 deletions apps/web/hooks/useColumnsEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ export function useColumnsEditor({ templateId }: UseSchemaProps) {
alternateKeys,
isRequired,
isUnique,
isFrozen,
regex,
dateFormats,
regexDescription,
selectValues,
sequence,
defaultValue,
allowMultiSelect,
}) => ({
Expand All @@ -51,12 +51,12 @@ export function useColumnsEditor({ templateId }: UseSchemaProps) {
alternateKeys,
isRequired,
isUnique,
isFrozen,
regex,
dateFormats,
defaultValue,
regexDescription,
selectValues,
sequence,
allowMultiSelect,
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
}
.index-cell {
text-align: center;
vertical-align: middle !important;
background-color: #f0f0f0 !important;
color: #222 !important;
padding: 5px !important;
Expand All @@ -21,6 +22,7 @@
vertical-align: middle;
}
.check-cell {
height: 24px !important;
cursor: pointer;
text-align: center;
padding: 0.5rem !important;
Expand All @@ -41,6 +43,7 @@
.checkbox {
display: inline-flex;
position: relative;
vertical-align: middle;
}

.checkbox__control {
Expand Down Expand Up @@ -104,7 +107,10 @@
border: 1px solid #ddd;

}

.ht_clone_left {
box-shadow: 2px 0px 6px 0px rgb(0 0 0 / 20%);
}

.dd-searchbox {
padding: 0.5rem;
background-color: #fff;
Expand Down
4 changes: 4 additions & 0 deletions apps/widget/src/components/Common/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import './HandsonTable.styles.min.css';
interface TableProps {
headings: string[];
allChecked?: boolean;
frozenColumns?: number;
height?: string | number;
width?: string | number;
afterRender?: () => void;
Expand Down Expand Up @@ -158,6 +159,7 @@ export const Table = forwardRef<HotTable, TableProps>(
allChecked,
onRowCheck,
onCheckAll,
frozenColumns = 2,
onValueChange,
}: TableProps,
gridRef
Expand Down Expand Up @@ -207,6 +209,8 @@ export const Table = forwardRef<HotTable, TableProps>(
columns={columnDefs}
colHeaders={headings}
afterRender={afterRender}
manualColumnResize
fixedColumnsLeft={frozenColumns}
licenseKey={HANDSONTABLE_LICENSE_KEY}
/>
);
Expand Down
3 changes: 3 additions & 0 deletions apps/widget/src/components/widget/Phases/Phase3/Phase3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function Phase3(props: IPhase3Props) {
reReviewData,
updateRecord,
onPageChange,
frozenColumns,
setReviewData,
setAllChecked,
deleteRecords,
Expand Down Expand Up @@ -73,6 +74,7 @@ export function Phase3(props: IPhase3Props) {
logAmplitudeEvent('CONFIRM');
onConfirmReview();
};
console.log(frozenColumns);

return (
<>
Expand All @@ -98,6 +100,7 @@ export function Phase3(props: IPhase3Props) {
</Flex>
<Table
ref={tableRef}
frozenColumns={frozenColumns}
width={tableWrapperDimensions.width}
height={tableWrapperDimensions.height}
onValueChange={(row, prop, oldVal, newVal) => {
Expand Down
Loading

0 comments on commit 8587e71

Please sign in to comment.