A core set of widgets, types, and services to create Fermilab applications.
- Provides a
ControlsRouterAppwidget to create a base, scaffold widget that has a standardized theme. - Provides a class that accesses the Fermilab GraphQL API.
- Provides a widget that authenticates users.
The latest, stable branch is v0.3, which is managed by the main branch. To
add this package to your application, add this dependency to your
pubspec.yaml file:
flutter_controls_core:
git:
url: https://github.com/fermi-ad/flutter-controls-core.git
ref: mainNOTE: This project is under very active development so calling this the
"stable" branch is a stretch. With each pull request, we will create a tag to
point to it. If the HEAD of main produces a regression, you can temporarily
use a tag as the git "ref:" parameter to get back to a more reliable version.
If you are building a native, mobile app, you need to add network permissions in order to use the GraphQL interface (this library is only useful when using the network!)
For Android targets, add the following tag to your AndroidManifest.xml file,
immediately after the opening manifest tag:
<uses-permission android:name="android.permission.INTERNET" />
For iOS targets, you need to open the .codeproj file in XCode and add the
permissions for network access in the application's profile. The appropriate
.xml files will be modified.
GraphQL support has been removed from this package. Your application now must
specify which GraphQL endpoints it wants to use. For instance, if your app
needs to read or set control system devices, it will need the ACSys GraphQL API.
In pubspec.yaml, you'll add
dependencies:
flutter_gql_acsys:
git:
url: https://github.com/fermi-ad/flutter-gql-acsys.git
ref: main
flutter_controls_core:
git:
url: https://github.com/fermi-ad/flutter-controls-core.git
ref: mainand where your application constructs the StandardApp, you specify the
provider of the GraphQL API:
final appTitle = "My App";
class App extends StatelessWidget {
const App();
@override
Widget build(final BuildContext context) => StandardApp(
title: appTitle,
providers: [ACSysProvider.factory()],
appBar: AppBar(title: const Text(appTitle)),
body: const MyAppBody(),
);
}The .build() method of your app's widgets can do ACSys.api(context) to get
the object that implements the GraphQL client interface. See the documentation
for the various GraphQL clients to see what's available.
OpenTelemetry tracing is enabled by default (opt-out) for all apps using this package's entrypoints (runFermiApp, runFermiRouterApp).
- Traces are exported to the console by default (see
ConsoleExporter).- In the future we will need a custom exporter for GraphQL. Good news is that otel is gRPC by default.
- You can override the exporter by calling
initOpenTelemetry(exporter: ...)before app startup. - Manual instrumentation is available for custom spans and events.
import 'package:flutter_controls_core/flutter_controls_core.dart';
final span = startSpan('operation', attributes: {'key': 'value'});
try {
// ... your code ...
addEvent(span, 'eventName', attributes: {'foo': 42});
} finally {
endSpan(span);
}Or use the convenience wrappers for automatic span management:
runWithSpan('operation', (span) {
// ... your code ...
});
await runWithSpanAsync('asyncOp', (span) async {
// ... your async code ...
});Use the AppTracer interface and the appTracer instance for testable code:
class MyService {
final AppTracer tracer;
MyService(this.tracer);
void doWork() {
tracer.runWithSpan('work', (span) {
// ...
});
}
}In tests, inject a mock tracer if needed.
To disable tracing, you can override initOpenTelemetry with a no-op exporter or skip calling it (not recommended for most apps).
For more details, see the API documentation in lib/src/otel_tracing.dart.
- Add metrics
- Add logging