test: add save date cell and checkbox cell (#2167)

* test: add save date cell and checkbox cell

* chore: add move field test

* ci: fix tauri build
This commit is contained in:
Nathan.fooo 2023-04-03 09:26:12 +08:00 committed by GitHub
parent fe524dbc78
commit cb149ec73d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 128 additions and 24 deletions

View file

@ -10,7 +10,7 @@ pub fn init_flowy_core() -> AppFlowyCore {
} }
data_path.push("data"); data_path.push("data");
std::env::set_var("RUST_LOG", "debug"); std::env::set_var("RUST_LOG", "trace");
let server_config = get_client_server_configuration().unwrap(); let server_config = get_client_server_configuration().unwrap();
let config = AppFlowyCoreConfig::new( let config = AppFlowyCoreConfig::new(
data_path.to_str().unwrap(), data_path.to_str().unwrap(),

View file

@ -108,7 +108,11 @@ export const EditRow = ({
const onDragEnd: OnDragEndResponder = (result) => { const onDragEnd: OnDragEndResponder = (result) => {
if (!result.destination?.index) return; if (!result.destination?.index) return;
void controller.moveField(result.source.droppableId, result.source.index, result.destination.index); void controller.moveField({
fieldId: result.source.droppableId,
fromIndex: result.source.index,
toIndex: result.destination.index,
});
}; };
return ( return (

View file

@ -12,6 +12,7 @@ import { RowInfo } from '../../stores/effects/database/row/row_cache';
import { RowController } from '../../stores/effects/database/row/row_controller'; import { RowController } from '../../stores/effects/database/row/row_controller';
import { import {
CellControllerBuilder, CellControllerBuilder,
CheckboxCellController,
DateCellController, DateCellController,
NumberCellController, NumberCellController,
SelectOptionCellController, SelectOptionCellController,
@ -126,6 +127,17 @@ export async function makeDateCellController(
return Some(builder.build() as DateCellController); return Some(builder.build() as DateCellController);
} }
export async function makeCheckboxCellController(
fieldId: string,
rowInfo: RowInfo,
databaseController: DatabaseController
): Promise<Option<CheckboxCellController>> {
const builder = await makeCellControllerBuilder(fieldId, rowInfo, FieldType.Checkbox, databaseController).then(
(result) => result.unwrap()
);
return Some(builder.build() as CheckboxCellController);
}
export async function makeURLCellController( export async function makeURLCellController(
fieldId: string, fieldId: string,
rowInfo: RowInfo, rowInfo: RowInfo,

View file

@ -8,10 +8,13 @@ import {
TestDeleteField, TestDeleteField,
TestDeleteRow, TestDeleteRow,
TestEditCell, TestEditCell,
TestEditCheckboxCell,
TestEditDateCell,
TestEditField, TestEditField,
TestEditTextCell, TestEditTextCell,
TestEditURLCell, TestEditURLCell,
TestGetSingleSelectFieldData, TestGetSingleSelectFieldData,
TestMoveField,
TestSwitchFromMultiSelectToText, TestSwitchFromMultiSelectToText,
TestSwitchFromSingleSelectToNumber, TestSwitchFromSingleSelectToNumber,
} from './TestGrid'; } from './TestGrid';
@ -37,9 +40,12 @@ export const TestAPI = () => {
<TestEditCell></TestEditCell> <TestEditCell></TestEditCell>
<TestEditTextCell></TestEditTextCell> <TestEditTextCell></TestEditTextCell>
<TestEditURLCell></TestEditURLCell> <TestEditURLCell></TestEditURLCell>
<TestEditDateCell></TestEditDateCell>
<TestEditCheckboxCell></TestEditCheckboxCell>
<TestCreateSelectOptionInCell></TestCreateSelectOptionInCell> <TestCreateSelectOptionInCell></TestCreateSelectOptionInCell>
<TestGetSingleSelectFieldData></TestGetSingleSelectFieldData> <TestGetSingleSelectFieldData></TestGetSingleSelectFieldData>
<TestEditField></TestEditField> <TestEditField></TestEditField>
<TestMoveField></TestMoveField>
<TestCreateNewField></TestCreateNewField> <TestCreateNewField></TestCreateNewField>
<TestDeleteField></TestDeleteField> <TestDeleteField></TestDeleteField>
<TestSwitchFromSingleSelectToNumber></TestSwitchFromSingleSelectToNumber> <TestSwitchFromSingleSelectToNumber></TestSwitchFromSingleSelectToNumber>

View file

@ -8,6 +8,7 @@ import {
} from '@/services/backend'; } from '@/services/backend';
import { Log } from '$app/utils/log'; import { Log } from '$app/utils/log';
import { import {
assert,
assertFieldName, assertFieldName,
assertNumberOfFields, assertNumberOfFields,
assertNumberOfRows, assertNumberOfRows,
@ -16,6 +17,8 @@ import {
createTestDatabaseView, createTestDatabaseView,
editTextCell, editTextCell,
findFirstFieldInfoWithFieldType, findFirstFieldInfoWithFieldType,
makeCheckboxCellController,
makeDateCellController,
makeMultiSelectCellController, makeMultiSelectCellController,
makeSingleSelectCellController, makeSingleSelectCellController,
makeTextCellController, makeTextCellController,
@ -27,6 +30,8 @@ import { TypeOptionController } from '$app/stores/effects/database/field/type_op
import { None, Some } from 'ts-results'; import { None, Some } from 'ts-results';
import { RowBackendService } from '$app/stores/effects/database/row/row_bd_svc'; import { RowBackendService } from '$app/stores/effects/database/row/row_bd_svc';
import { makeNumberTypeOptionContext } from '$app/stores/effects/database/field/type_option/type_option_context'; import { makeNumberTypeOptionContext } from '$app/stores/effects/database/field/type_option/type_option_context';
import { CalendarData } from '$app/stores/effects/database/cell/controller_builder';
import { DatabaseEventMoveField } from '@/services/backend/events/flowy-database';
export const RunAllGridTests = () => { export const RunAllGridTests = () => {
async function run() { async function run() {
@ -138,6 +143,57 @@ async function testEditURLCell() {
await new Promise((resolve) => setTimeout(resolve, 200)); await new Promise((resolve) => setTimeout(resolve, 200));
} }
async function testEditDateCell() {
const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
const databaseController = await openTestDatabase(view.id);
await databaseController.open().then((result) => result.unwrap());
const typeOptionController = new TypeOptionController(view.id, None, FieldType.DateTime);
await typeOptionController.initialize();
const row = databaseController.databaseViewCache.rowInfos[0];
const dateCellController = await makeDateCellController(typeOptionController.fieldId, row, databaseController).then(
(result) => result.unwrap()
);
dateCellController.subscribeChanged({
onCellChanged: (content) => {
const pb = content.unwrap();
Log.info('Receive date data:', pb.date, pb.time);
},
});
const date = new CalendarData(new Date(), true, '13:00');
await dateCellController.saveCellData(date);
await new Promise((resolve) => setTimeout(resolve, 200));
}
async function testCheckboxCell() {
const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
const databaseController = await openTestDatabase(view.id);
await databaseController.open().then((result) => result.unwrap());
const typeOptionController = new TypeOptionController(view.id, None, FieldType.Checkbox);
await typeOptionController.initialize();
const row = databaseController.databaseViewCache.rowInfos[0];
const checkboxCellController = await makeCheckboxCellController(
typeOptionController.fieldId,
row,
databaseController
).then((result) => result.unwrap());
checkboxCellController.subscribeChanged({
onCellChanged: (content) => {
const pb = content.unwrap();
Log.info('Receive checkbox data:', pb);
},
});
await checkboxCellController.saveCellData('true');
await new Promise((resolve) => setTimeout(resolve, 200));
}
async function testCreateRow() { async function testCreateRow() {
const view = await createTestDatabaseView(ViewLayoutTypePB.Grid); const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
const databaseController = await openTestDatabase(view.id); const databaseController = await openTestDatabase(view.id);
@ -196,6 +252,24 @@ async function testCreateOptionInCell() {
await databaseController.dispose(); await databaseController.dispose();
} }
async function testMoveField() {
const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
const databaseController = await openTestDatabase(view.id);
await databaseController.open().then((result) => result.unwrap());
databaseController.subscribe({
onFieldsChanged: (value) => {
Log.info('Receive fields data:', value);
},
});
const fieldInfos = [...databaseController.fieldController.fieldInfos];
const field_id = fieldInfos[0].field.id;
await databaseController.moveField({ fieldId: field_id, fromIndex: 0, toIndex: 1 });
await new Promise((resolve) => setTimeout(resolve, 200));
assert(databaseController.fieldController.fieldInfos[1].field.id === field_id);
}
async function testGetSingleSelectFieldData() { async function testGetSingleSelectFieldData() {
const view = await createTestDatabaseView(ViewLayoutTypePB.Grid); const view = await createTestDatabaseView(ViewLayoutTypePB.Grid);
const databaseController = await openTestDatabase(view.id); const databaseController = await openTestDatabase(view.id);
@ -360,6 +434,12 @@ export const TestEditTextCell = () => {
export const TestEditURLCell = () => { export const TestEditURLCell = () => {
return TestButton('Test editing URL cell', testEditURLCell); return TestButton('Test editing URL cell', testEditURLCell);
}; };
export const TestEditDateCell = () => {
return TestButton('Test editing date cell', testEditDateCell);
};
export const TestEditCheckboxCell = () => {
return TestButton('Test editing checkbox cell', testCheckboxCell);
};
export const TestCreateRow = () => { export const TestCreateRow = () => {
return TestButton('Test create row', testCreateRow); return TestButton('Test create row', testCreateRow);
}; };
@ -382,6 +462,9 @@ export const TestSwitchFromMultiSelectToText = () => {
return TestButton('Test switch from multi-select to text column', testSwitchFromMultiSelectToRichText); return TestButton('Test switch from multi-select to text column', testSwitchFromMultiSelectToRichText);
}; };
export const TestMoveField = () => {
return TestButton('Test move field', testMoveField);
};
export const TestEditField = () => { export const TestEditField = () => {
return TestButton('Test edit the column name', testEditField); return TestButton('Test edit the column name', testEditField);
}; };

View file

@ -23,7 +23,7 @@ export type SelectOptionCellController = CellController<SelectOptionCellDataPB,
export type DateCellController = CellController<DateCellDataPB, CalendarData>; export type DateCellController = CellController<DateCellDataPB, CalendarData>;
export class CalendarData { export class CalendarData {
constructor(public readonly date: Date, public readonly time?: string) {} constructor(public readonly date: Date, public readonly includeTime: boolean, public readonly time?: string) {}
} }
export type URLCellController = CellController<URLCellDataPB, string>; export type URLCellController = CellController<URLCellDataPB, string>;

View file

@ -25,11 +25,12 @@ export class DateCellDataPersistence extends CellDataPersistence<CalendarData> {
save(data: CalendarData): Promise<Result<void, FlowyError>> { save(data: CalendarData): Promise<Result<void, FlowyError>> {
const payload = DateChangesetPB.fromObject({ cell_path: _makeCellPath(this.cellIdentifier) }); const payload = DateChangesetPB.fromObject({ cell_path: _makeCellPath(this.cellIdentifier) });
payload.date = data.date.getUTCMilliseconds.toString(); payload.date = ((data.date.getTime() / 1000) | 0).toString();
payload.is_utc = true; payload.is_utc = true;
if (data.time !== undefined) { if (data.time !== undefined) {
payload.time = data.time; payload.time = data.time;
} }
payload.include_time = data.includeTime;
return DatabaseEventUpdateDateCell(payload); return DatabaseEventUpdateDateCell(payload);
} }
} }

View file

@ -98,16 +98,6 @@ export class DatabaseBackendService {
return DatabaseEventMoveGroup(payload); return DatabaseEventMoveGroup(payload);
}; };
moveField = (fieldId: string, fromIndex: number, toIndex: number) => {
const payload = MoveFieldPayloadPB.fromObject({
view_id: this.viewId,
field_id: fieldId,
from_index: fromIndex,
to_index: toIndex,
});
return DatabaseEventMoveField(payload);
};
/// Get all fields in database /// Get all fields in database
getFields = async (fieldIds?: FieldIdPB[]) => { getFields = async (fieldIds?: FieldIdPB[]) => {
const payload = GetFieldPayloadPB.fromObject({ view_id: this.viewId }); const payload = GetFieldPayloadPB.fromObject({ view_id: this.viewId });
@ -125,6 +115,16 @@ export class DatabaseBackendService {
return DatabaseEventGetGroup(payload); return DatabaseEventGetGroup(payload);
}; };
moveField = (params: { fieldId: string; fromIndex: number; toIndex: number }) => {
const payload = MoveFieldPayloadPB.fromObject({
view_id: this.viewId,
field_id: params.fieldId,
from_index: params.fromIndex,
to_index: params.toIndex,
});
return DatabaseEventMoveField(payload);
};
/// Get all groups in database /// Get all groups in database
/// It should only call once after the board open /// It should only call once after the board open
loadGroups = () => { loadGroups = () => {

View file

@ -1,7 +1,7 @@
import { DatabaseBackendService } from './database_bd_svc'; import { DatabaseBackendService } from './database_bd_svc';
import { FieldController, FieldInfo } from './field/field_controller'; import { FieldController, FieldInfo } from './field/field_controller';
import { DatabaseViewCache } from './view/database_view_cache'; import { DatabaseViewCache } from './view/database_view_cache';
import { DatabasePB, FlowyError, GroupPB } from '@/services/backend'; import { DatabasePB, GroupPB, FlowyError } from '@/services/backend';
import { RowChangedReason, RowInfo } from './row/row_cache'; import { RowChangedReason, RowInfo } from './row/row_cache';
import { Err, Ok } from 'ts-results'; import { Err, Ok } from 'ts-results';
import { DatabaseGroupController } from './group/group_controller'; import { DatabaseGroupController } from './group/group_controller';
@ -102,8 +102,8 @@ export class DatabaseController {
return this.backendService.moveGroup(fromGroupId, toGroupId); return this.backendService.moveGroup(fromGroupId, toGroupId);
}; };
moveField = (fieldId: string, fromIndex: number, toIndex: number) => { moveField = (params: { fieldId: string; fromIndex: number; toIndex: number }) => {
return this.backendService.moveField(fieldId, fromIndex, toIndex); return this.backendService.moveField(params);
}; };
private loadGroup = async () => { private loadGroup = async () => {

View file

@ -36,8 +36,8 @@ export class FieldController {
} }
}; };
subscribe = (callbacks: { onNumOfFieldsChanged?: (fieldInfos: readonly FieldInfo[]) => void}) => { subscribe = (callbacks: { onNumOfFieldsChanged?: (fieldInfos: readonly FieldInfo[]) => void }) => {
this.numOfFieldsNotifier.observer.subscribe((fieldInfos) => { this.numOfFieldsNotifier.observer.subscribe((fieldInfos) => {
callbacks.onNumOfFieldsChanged?.(fieldInfos); callbacks.onNumOfFieldsChanged?.(fieldInfos);
}); });
}; };
@ -63,12 +63,10 @@ export class FieldController {
} }
const deletedFieldIds = deletedFields.map((field) => field.field_id); const deletedFieldIds = deletedFields.map((field) => field.field_id);
const predicate = (element: FieldInfo) => { const predicate = (element: FieldInfo): boolean => {
!deletedFieldIds.includes(element.field.id); return !deletedFieldIds.includes(element.field.id);
}; };
const newFieldInfos = [...this.fieldInfos]; this.numOfFieldsNotifier.fieldInfos = [...this.fieldInfos].filter(predicate);
newFieldInfos.filter(predicate);
this.numOfFieldsNotifier.fieldInfos = newFieldInfos;
}; };
private _insertFields = (insertedFields: IndexFieldPB[]) => { private _insertFields = (insertedFields: IndexFieldPB[]) => {