Skip to content

Commit

Permalink
feat(dashboard): added action selection button and can basically star…
Browse files Browse the repository at this point in the history
…t to select service, action & reaction

evol(about): add ids to paylaod

Signed-off-by: Mael-RABOT <[email protected]>

feat(Models): add ids in System and Event field in models

evol(about): add ids to paylaod

Signed-off-by: Mael-RABOT <[email protected]>

feat(user): add user page

Signed-off-by: Mael-RABOT <[email protected]>

feat(token): add token model

Signed-off-by: Mathieu <[email protected]>

hotfix(rabbitmq): fix rabbitmq build

Signed-off-by: Mathieu <[email protected]>

feat(workflows): add table

Signed-off-by: Mael-RABOT <[email protected]>

fix(Workflow): Workflow are correctly created with new schema (#136)

feat(services): can select services and actions from about.json

feat(workflows): made cards prettier, can now select actions and reactions and inputting parameters value

feat(workflows): create button

feat(oauth): added pages to link our account with microsoft, spotify google and discord oauth (only microsoft fonctional)

feat(workflow): handle the creation of workflow
  • Loading branch information
sambrus authored and mathieu-brl committed Dec 10, 2024
1 parent 441e191 commit 1c92f03
Show file tree
Hide file tree
Showing 67 changed files with 2,072 additions and 253 deletions.
Binary file added client_mobile/assets/images/discord.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client_mobile/assets/images/google.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added client_mobile/assets/images/spotify.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client_mobile/assets/images/spotify_green.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions client_mobile/lib/data/action.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:client_mobile/data/parameter.dart';

class WorkflowActionReaction {
final int id;
final String name;
final String description;
final List<Parameter> parameters;
String? serviceName;
int? serviceId;

WorkflowActionReaction({
required this.id,
required this.name,
required this.description,
required this.parameters,
this.serviceName,
this.serviceId
});

factory WorkflowActionReaction.fromJson(Map<String, dynamic> json) {
return WorkflowActionReaction(
id: json['id'],
name: json['name'],
description: json['description'] ?? "",
parameters: json['parameters'] != null
? (json['parameters'] as List)
.map((param) => Parameter.fromJson(param))
.toList()
: [],
);
}

Map<String, dynamic> toJson(String type) {
return {
'id': id,
'name': name,
'type': type,
'description': description,
'parameters': parameters.map((p) => p.toJson()).toList(),
};
}
}
29 changes: 29 additions & 0 deletions client_mobile/lib/data/parameter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class Parameter {
final String name;
final String description;
final String type;
String? value;

Parameter({
required this.name,
required this.description,
required this.type,
this.value,
});

factory Parameter.fromJson(Map<String, dynamic> json) {
return Parameter(
name: json['name'],
description: json['description'] ?? "",
type: json['type'],
);
}

Map<String, dynamic> toJson() {
return {
'name': name,
'type': type,
'value': value
};
}
}
52 changes: 52 additions & 0 deletions client_mobile/lib/data/service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import 'package:client_mobile/data/action.dart';

class WorkflowService {
final int id;
final String name;
final List<WorkflowActionReaction> actions;
final List<WorkflowActionReaction> reactions;

WorkflowService({
required this.id,
required this.name,
required this.actions,
required this.reactions,
});

factory WorkflowService.fromJson(Map<String, dynamic> json) {
try {
return WorkflowService(
id: json['id'] ?? 0,
name: json['name'] ??
'Unknown',
actions: _parseActionsOrReactions(json['actions']),
reactions: _parseActionsOrReactions(json['reactions']),
);
} catch (e) {
print('Error parsing WorkflowService: $e');
return WorkflowService(
id: 0, name: 'Unknown', actions: [], reactions: []);
}
}

static List<WorkflowActionReaction> _parseActionsOrReactions(dynamic data) {
if (data == null) {
return [];
}
if (data is List) {
return data.map((item) => WorkflowActionReaction.fromJson(item)).toList();
} else {
print('Expected a list for actions or reactions, but got: $data');
return [];
}
}

Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'actions': actions.map((a) => a.toJson("action")).toList(),
'reactions': reactions.map((r) => r.toJson("reaction")).toList(),
};
}
}
36 changes: 36 additions & 0 deletions client_mobile/lib/data/service_metadata.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:flutter/material.dart';

class ServiceMetadata {
final String name;
final Color color;
final String imagePath;

ServiceMetadata({
required this.name,
required this.color,
required this.imagePath,
});

static List<ServiceMetadata> services = [
ServiceMetadata(
name: "spotify",
color: Colors.green,
imagePath: 'assets/images/spotify.png'),
ServiceMetadata(
name: "discord",
color: Colors.lightBlue,
imagePath: 'assets/images/discord.png'),
ServiceMetadata(
name: "microsoft",
color: Colors.grey,
imagePath: 'assets/images/microsoft.png'),
ServiceMetadata(
name: "google",
color: Colors.amber,
imagePath: 'assets/images/google.png'),
];

static ServiceMetadata? getServiceByName(String name) {
return services.firstWhere((service) => service.name == name);
}
}
38 changes: 38 additions & 0 deletions client_mobile/lib/data/workflow.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'package:client_mobile/data/action.dart';
import 'package:flutter/gestures.dart';

class WorkflowEvent
{
final WorkflowActionReaction action;
final String type;

WorkflowEvent({
required this.action,
required this.type
});
}


class Workflow {
final String name;
final String description;
final List<int> servicesId;
final List<WorkflowEvent> events;

Workflow({
required this.name,
required this.description,
required this.servicesId,
required this.events,
});


Map<String, dynamic> toJson() {
return {
'name': name,
'description': description,
'services': servicesId,
'events': events.map((a) => a.action.toJson(a.type)).toList(),
};
}
}
2 changes: 1 addition & 1 deletion client_mobile/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Future<void> main() async {
routes: [
GoRoute(
path: '/',
builder: (context, state) => HomePage(),
builder: (context, state) => const HomePage(),
),
GoRoute(
path: '/login',
Expand Down
2 changes: 1 addition & 1 deletion client_mobile/lib/pages/auth/login.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class _LoginPageState extends State<LoginPage> {
},
label: "Sign in with Microsoft",
image: Image.asset(
"assets/images/microsoft_logo.png",
"assets/images/microsoft.png",
width: 40,
height: 30,
),
Expand Down
2 changes: 1 addition & 1 deletion client_mobile/lib/pages/auth/register.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class _RegisterPageState extends State<RegisterPage> {
},
label: "Sign in with Microsoft",
image: Image.asset(
"assets/images/microsoft_logo.png",
"assets/images/microsoft.png",
width: 40,
height: 30,
),
Expand Down
70 changes: 70 additions & 0 deletions client_mobile/lib/pages/dashboard/action_selection_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:client_mobile/data/action.dart';
import 'package:client_mobile/data/parameter.dart';
import 'package:client_mobile/data/service.dart';
import 'package:flutter/material.dart';

class ActionSelectionPage extends StatelessWidget {
final WorkflowService service;
final Function(WorkflowActionReaction, WorkflowService) onActionSelected;
final List<WorkflowActionReaction> actions;

const ActionSelectionPage(
{super.key,
required this.service,
required this.onActionSelected,
required this.actions});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Select Action/Reaction'),
),
body: ListView.builder(
itemCount: actions.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(actions[index].name),
onTap: () async {
for (var param in actions[index].parameters) {
String? updatedValue =
await _showParameterDialog(context, param);
param.value = updatedValue;
}
onActionSelected(actions[index], service);
Navigator.popUntil(context, (route) => route.isFirst);
},
);
},
),
);
}

Future<String?> _showParameterDialog(
BuildContext context, Parameter parameter) async {
TextEditingController controller = TextEditingController();

return showDialog<String>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Enter value for ${parameter.name}'),
content: TextField(
controller: controller,
decoration: InputDecoration(
hintText: 'Enter value for ${parameter.name}',
),
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context, controller.text);
},
child: const Text('OK'),
),
],
);
},
);
}
}
48 changes: 31 additions & 17 deletions client_mobile/lib/pages/dashboard/dashboard.dart
Original file line number Diff line number Diff line change
@@ -1,30 +1,44 @@
import 'package:client_mobile/services/login/auth_service.dart';
import 'package:client_mobile/pages/dashboard/service_connection.dart';
import 'package:client_mobile/pages/dashboard/workflow.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

class DashboardPage extends StatefulWidget {
const DashboardPage({super.key});

@override
State<DashboardPage> createState() => _DashboardPageState();
_DashboardPageState createState() => _DashboardPageState();
}

class _DashboardPageState extends State<DashboardPage> {
int _currentIndex = 0; // Pour suivre l'index actuel

final List<Widget> _pages = [
WorkflowPage(), // Votre page actuelle avec les boutons Action et Réaction
ServiceConnectionPage(), // Une nouvelle page pour la connexion des services
];

void _onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: const Center(
child: Text("Dashboard "),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
bool hasLogout = await AuthService.logout();
if (hasLogout)
context.pushReplacement("/login");
},
tooltip: 'Logout',
child: const Icon(Icons.login),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: _onTabTapped,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Services',
),
],
),
);
}
}
}
Loading

0 comments on commit 1c92f03

Please sign in to comment.