mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-04-24 22:57:12 -04:00
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:
parent
fe524dbc78
commit
cb149ec73d
10 changed files with 128 additions and 24 deletions
|
@ -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(),
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = () => {
|
||||||
|
|
|
@ -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 () => {
|
||||||
|
|
|
@ -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[]) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue