Skip to content

Commit

Permalink
Fixing FieldsDialog
Browse files Browse the repository at this point in the history
  • Loading branch information
enm10k committed Jun 29, 2024
1 parent 6169070 commit 87d103e
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 157 deletions.
136 changes: 34 additions & 102 deletions lib/features/core/components/dialog/fields_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,103 +1,54 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nocodb/common/components/not_implementing_dialog.dart';
import 'package:nocodb/common/flash_wrapper.dart';
import 'package:nocodb/common/logger.dart';
import 'package:nocodb/features/core/providers/fields_provider.dart';
import 'package:nocodb/features/core/providers/providers.dart';
import 'package:nocodb/nocodb_sdk/client.dart';
import 'package:nocodb/nocodb_sdk/models.dart' as model;

model.NcTableColumn getTableColumn(
model.NcViewColumn viewColumn,
List<model.NcTableColumn> tableColumns,
) =>
tableColumns
.where((tableColumn) => tableColumn.id == viewColumn.fkColumnId)
.firstOrNull ??
tableColumns.first;
import 'package:nocodb/nocodb_sdk/models.dart';

class FieldsDialog extends HookConsumerWidget {
const FieldsDialog({
super.key,
});
static const debug = true;

_debugViewColumns(
List<model.NcViewColumn> viewColumns,
List<model.NcTableColumn> tableColumns,
) {
viewColumns.asMap().forEach((index, column) {
final tableColumn = getTableColumn(column, tableColumns);
logger.info('$index ${tableColumn.title}');
});
}

@override
Widget build(BuildContext context, WidgetRef ref) {
final isLoaded = ref.watch(isLoadedProvider);
if (!isLoaded) {
return const CircularProgressIndicator();
}
final table = ref.watch(tableProvider)!;
final view = ref.watch(viewProvider)!;

final viewColumns_ = ref.watch(viewColumnListProvider(view.id));
if (!viewColumns_.hasValue) {
return const SizedBox();
}

final viewColumns = viewColumns_.value!;

// TODO: Move to provider
final filteredViewColumns = viewColumns.where((viewColumn) {
final tableColumn = getTableColumn(viewColumn, table.columns);

return view.showSystemFields ? true : !tableColumn.isSystem;
}).toList()
..sort((a, b) => a.order.compareTo(b.order));
return ref.watch(fieldsProvider).when(
data: (data) => _build(context, ref, data),
error: (e, s) => Text('$e\n$s'),
loading: () => const Center(child: CircularProgressIndicator()),
);
}

final List<Widget> children = filteredViewColumns.map(
(viewColumn) {
final column = getTableColumn(viewColumn, table.columns);
Widget _build(BuildContext context, WidgetRef ref, List<NcViewColumn> vcs) {
final view = ref.watch(viewProvider)!;
final table = ref.watch(tableProvider)!;
final List<Widget> children = vcs.map(
(vc) {
final tc = vc.toTableColumn(table.columns)!;
return CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
key: Key(viewColumn.id),
title: Text(column.title),
value: viewColumn.show,
key: Key(vc.id),
title:
kDebugMode ? Text('${tc.title} (${vc.order})') : Text(tc.title),
value: vc.show,
onChanged: (value) async {
if (column.pv) {
await showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('${column.title} is display value'),
content: const Text('You cannot hide display value.'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
);
try {
await ref.read(fieldsProvider.notifier).show(vc, value == true);
} catch (error, stackTrace) {
if (context.mounted) {
notifyError(context, error, stackTrace);
}
}
// TODO: The following logic should be integrated to provider.
await api
.dbViewColumnUpdateShow(
column: viewColumn,
show: value == true,
)
.then(
(_) => ref.invalidate(viewColumnListProvider),
)
.onError(
(error, stackTrace) => notifyError(
context,
error,
stackTrace,
),
);
},
);
},
Expand All @@ -115,35 +66,16 @@ class FieldsDialog extends HookConsumerWidget {
width: double.maxFinite,
child: ReorderableListView(
shrinkWrap: true,
onReorder: (oldIndex, newIndex) {
// TODO: Fix. Current behavior is slightly different from nc-gui.
// https://github.com/nocodb/nocodb/blob/fbe406c51176709d1f8779d8d95405f52a869079/packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue#L71-L85
final newViewColumns = [...viewColumns];

if (debug) {
_debugViewColumns(viewColumns, table.columns);
}
final movingColumn = newViewColumns.removeAt(oldIndex);
newViewColumns.insert(newIndex, movingColumn);

if (debug) {
logger.info(
'moving ${getTableColumn(movingColumn, table.columns).title}',
);
_debugViewColumns(viewColumns, table.columns);
}

// TODO: The following logic should be integrated to provider.
newViewColumns.asMap().forEach((index, viewColumn) async {
final newOrder = index + 1;
if (viewColumn.order != newOrder) {
await api.dbViewColumnUpdateOrder(
column: viewColumn,
order: newOrder,
);
onReorder: (oldIndex, newIndex) async {
try {
await ref
.read(fieldsProvider.notifier)
.reorder(oldIndex, newIndex);
} catch (error, stackTrace) {
if (context.mounted) {
notifyError(context, error, stackTrace);
}
});
ref.invalidate(viewColumnListProvider);
}
},
children: children,
),
Expand Down
7 changes: 3 additions & 4 deletions lib/features/core/components/views/grid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:nocodb/common/extensions.dart';
import 'package:nocodb/common/flash_wrapper.dart';
import 'package:nocodb/common/logger.dart';
import 'package:nocodb/features/core/components/cell.dart';
import 'package:nocodb/features/core/providers/fields_provider.dart';
import 'package:nocodb/features/core/providers/providers.dart';
import 'package:nocodb/nocodb_sdk/models.dart' as model;
import 'package:nocodb/nocodb_sdk/symbols.dart';
Expand Down Expand Up @@ -67,11 +68,9 @@ class Grid extends HookConsumerWidget {
}

final tables = ref.watch(tablesProvider)!;
final view = ref.watch(viewProvider)!;

final columns = ref.watch(fieldsProvider(view)).valueOrNull?.toList() ?? [];
final columns = ref.watch(gridFieldsProvider).valueOrNull?.toList() ?? [];
logger
..info('view: ${view.title} has ${columns.length} columns(s).')
..info('${columns.length} columns(s).')
..info('columns: ${columns.map((e) => e.title).toList()}');

final dataRow = ref.watch(dataRowsProvider).valueOrNull;
Expand Down
1 change: 1 addition & 0 deletions lib/features/core/pages/row_editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nocodb/common/flash_wrapper.dart';
import 'package:nocodb/features/core/components/editor.dart';
import 'package:nocodb/features/core/providers/fields_provider.dart';
import 'package:nocodb/features/core/providers/providers.dart';
import 'package:nocodb/features/core/utils.dart';
import 'package:nocodb/nocodb_sdk/models.dart' as model;
Expand Down
17 changes: 9 additions & 8 deletions lib/features/core/pages/sheet.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nocodb/common/flash_wrapper.dart';
import 'package:nocodb/features/core/components/dialog/search_dialog.dart';
import 'package:nocodb/features/core/components/toolbar.dart';
import 'package:nocodb/features/core/components/view_switcher.dart';
Expand Down Expand Up @@ -49,12 +50,6 @@ class SheetPage extends HookConsumerWidget {
BottomAppBarButton(
iconData: Icons.add_circle_outline,
onPressed: () async {
final table = ref.watch(tableProvider);
final view = ref.watch(viewProvider);
if (table == null || view == null) {
return;
}

await const RowEditorRoute().push(context);
},
),
Expand All @@ -67,8 +62,14 @@ class SheetPage extends HookConsumerWidget {
),
BottomAppBarButton(
iconData: Icons.refresh,
onPressed: () {
ref.invalidate(dataRowsProvider);
onPressed: () async {
try {
await ref.read(viewProvider.notifier).reload();
} catch (error, stackTrace) {
if (context.mounted) {
notifyError(context, error, stackTrace);
}
}
},
),
],
Expand Down
106 changes: 106 additions & 0 deletions lib/features/core/providers/fields_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import 'package:collection/collection.dart';
import 'package:nocodb/common/logger.dart';
import 'package:nocodb/features/core/providers/providers.dart';
import 'package:nocodb/features/core/providers/utils.dart';
import 'package:nocodb/nocodb_sdk/client.dart';
import 'package:nocodb/nocodb_sdk/models.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'fields_provider.g.dart';

@Riverpod(keepAlive: true)
Future<List<NcViewColumn>> viewColumnList(
ViewColumnListRef ref,
String viewId,
) async =>
unwrap(await api.dbViewColumnList(viewId: viewId));

@Riverpod()
class _FieldsBase extends _$FieldsBase {
@override
Future<List<NcViewColumn>> build() async {
final view = ref.watch(viewProvider)!;
return (await ref.watch(viewColumnListProvider(view.id).future))
..sort((a, b) => a.order.compareTo(b.order));
}
}

@Riverpod()
class Fields extends _$Fields {
@override
Future<List<NcViewColumn>> build() async {
final table = ref.watch(tableProvider)!;
final view = ref.watch(viewProvider)!;
return (await ref.watch(_fieldsBaseProvider.future))
.filter(table, view, excludePv: true, ignoreShow: true)
.toList();
}

Future<void> show(NcViewColumn vc, bool b) async {
await api.dbViewColumnUpdateShow(
column: vc,
show: b,
);
ref.invalidate(_fieldsBaseProvider);
}

_debugViewColumns(
List<NcViewColumn> vcs,
List<NcTableColumn> tcs,
) {
vcs.asMap().forEach((index, vc) {
final tc = vc.toTableColumn(tcs)!;
logger.info('$index ${tc.title} ${vc.order}');
});
}

static const debug = true;
// TODO: Fix. Current behavior is slightly different from nc-gui.
// https://github.com/nocodb/nocodb/blob/fbe406c51176709d1f8779d8d95405f52a869079/packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue#L71-L85
Future<void> reorder(int oldIndex, int newIndex) async {
final table = ref.watch(tableProvider)!;
// TODO: Fix. Current behavior is slightly different from nc-gui.
// https://github.com/nocodb/nocodb/blob/fbe406c51176709d1f8779d8d95405f52a869079/packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue#L71-L85
final vcs = [...state.value!];

if (debug) {
_debugViewColumns(vcs, table.columns);
}
final vc = vcs.removeAt(oldIndex);
vcs.insert(newIndex, vc);

if (debug) {
logger.info(
// 'moving ${getTableColumn(vc, table.columns).title}',
'moving ${vc.toTableColumn(table.columns)?.title} from $oldIndex to $newIndex',
);
_debugViewColumns(vcs, table.columns);
}

// TODO: The following logic should be integrated to provider.
vcs.asMap().forEach((index, viewColumn) async {
final newOrder = index + 1;
if (viewColumn.order != newOrder) {
await api.dbViewColumnUpdateOrder(
column: viewColumn,
order: newOrder,
);
}
});
ref.invalidate(viewColumnListProvider);
}
}

@Riverpod()
class GridFields extends _$GridFields {
@override
Future<List<NcTableColumn>> build() async {
final table = ref.watch(tableProvider)!;
final view = ref.watch(viewProvider)!;
return (await ref.watch(_fieldsBaseProvider.future))
.filter(table, view)
.map((v) => v.toTableColumn(table.columns))
.whereNotNull()
.toList();
}
}
Loading

0 comments on commit 87d103e

Please sign in to comment.