From bb80fe9e424c8b05688748f399aa34ae02b6d505 Mon Sep 17 00:00:00 2001 From: Joey Boerwinkel Date: Tue, 2 Jul 2024 12:22:14 +0200 Subject: [PATCH] feat(flutter_availability_data_interface): define the models and interface for templates --- .../lib/src/data_interface.dart | 47 ++++- .../lib/src/models/templates.dart | 160 ++++++++++++++++++ 2 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 packages/flutter_availability_data_interface/lib/src/models/templates.dart diff --git a/packages/flutter_availability_data_interface/lib/src/data_interface.dart b/packages/flutter_availability_data_interface/lib/src/data_interface.dart index ca0e62e..b040d89 100644 --- a/packages/flutter_availability_data_interface/lib/src/data_interface.dart +++ b/packages/flutter_availability_data_interface/lib/src/data_interface.dart @@ -1,4 +1,5 @@ import "package:flutter_availability_data_interface/src/models/availability.dart"; +import "package:flutter_availability_data_interface/src/models/templates.dart"; /// A base interface that defines the communication from the availability user /// story to its persistance solution. @@ -23,18 +24,58 @@ abstract interface class AvailabilityDataInterface { /// [userId] and [availabilityId] Future deleteAvailabilityForUser(String userId, String availabilityId); - /// Updates the availability for the given [userId] and [availabilityId] + /// Updates the availability for the given [userId] and [availabilityId]. /// - /// This will not work if no [availabilityId] for [userId] exists + /// This will not work if no [availabilityId] for [userId] exists. Future updateAvailabilityForUser( String userId, String availabilityId, AvailabilityModel updatedModel, ); - /// Creates a new persistant representation of an availability model + /// Creates a new persistant representation of an availability model. Future createAvailabilityForUser( String userId, AvailabilityModel availability, ); + + /// Retrieves a list of templates for the given [userId]. + /// + /// Whether this is a one time value or a continuous stream of values is up to + /// the implementation. + Stream> getTemplatesForUser(String userId); + + /// Retrieves a specific template for the given + /// [userId] and [templateId] + Stream getTemplateForUserById( + String userId, + String templateId, + ); + + /// Deletes a specific template for the given + /// [userId] and [templateId] + Future deleteTemplateForUser(String userId, String templateId); + + /// Updates the availability for the given [userId] and [templateId]. + /// + /// This will not work if no [templateId] for [userId] exists. + Future updateTemplateForUser( + String userId, + String templateId, + AvailabilityTemplateModel updatedModel, + ); + + /// Creates a new persistant representation of an availability template model. + Future createTemplateForUser( + String userId, + AvailabilityTemplateModel template, + ); + + /// Applies a given [template] for a [userId] and creates new availabilities. + Future> applyTemplateForUser( + String userId, + AvailabilityTemplateModel template, + DateTime start, + DateTime end, + ); } diff --git a/packages/flutter_availability_data_interface/lib/src/models/templates.dart b/packages/flutter_availability_data_interface/lib/src/models/templates.dart new file mode 100644 index 0000000..4393454 --- /dev/null +++ b/packages/flutter_availability_data_interface/lib/src/models/templates.dart @@ -0,0 +1,160 @@ +import "package:flutter_availability_data_interface/src/models/availability.dart"; + +/// A limited set of different availability template types +enum AvailabilityTemplateType { + /// A template that applies to any day, regardless of when it is. + day, + + /// A template that applies on a per week basis, where for each day of the + /// week a different template is given + week; +} + +/// A template to mass create availabilities +class AvailabilityTemplateModel { + /// Create a new availability template + const AvailabilityTemplateModel({ + required this.userId, + required this.name, + required this.color, + required this.templateType, + required this.templateData, + this.id, + }); + + /// The identifier for this template + final String? id; + + /// The user for whom the template is saved. + final String userId; + + /// The name by which the template can be visually identified + final String name; + + /// The color by which the template can be visually identified + final int color; + + /// The type of template this is. + /// + /// This is used for parsing the template data to a model + final AvailabilityTemplateType templateType; + + /// The specific data for this template + final TemplateData templateData; +} + +/// Used as the key for defining week-based templates +enum WeekDay { + /// Representation for the first day in the week + monday, + + /// Representation for the second day in the week + tuesday, + + /// Representation for the third day in the week + wednesday, + + /// Representation for the fourth day in the week + thursday, + + /// Representation for the fifth day in the week + friday, + + /// Representation for the sixth day in the week + saturday, + + /// Representation for the seventh day in the week + sunday; + + /// Finds the Weekday based on the given [dateTime], where + /// [DateTime.monday] should return [WeekDay.monday]. + /// + /// The datetime is 1-indexed, whilst the weekday is 0-indexed, hence that + /// a -1 operation is applied to the weekday of the [dateTime] + factory WeekDay.fromDateTime(DateTime dateTime) => + WeekDay.values[dateTime.weekday - 1]; +} + +/// Defines the interface all templatedata implementation need to apply to +/// +/// ignore: one_member_abstracts +abstract interface class TemplateData { + /// Applies the current template to all days found between [start] and [end], + /// inclusive + List apply({ + required DateTime start, + required DateTime end, + }); +} + +/// A week based template data structure +class WeekTemplateData implements TemplateData { + /// Create a new week based template + const WeekTemplateData({required Map data}) + : _data = data; + + /// Alternative way of constructing a week based template for explicit weekday + /// assignments + factory WeekTemplateData.forDays({ + DayTemplateData? monday, + DayTemplateData? tuesday, + DayTemplateData? wednesday, + DayTemplateData? thursday, + DayTemplateData? friday, + DayTemplateData? saturday, + DayTemplateData? sunday, + }) => + WeekTemplateData( + data: { + if (monday != null) WeekDay.monday: monday, + if (tuesday != null) WeekDay.tuesday: tuesday, + if (wednesday != null) WeekDay.wednesday: wednesday, + if (thursday != null) WeekDay.thursday: thursday, + if (friday != null) WeekDay.friday: friday, + if (saturday != null) WeekDay.saturday: saturday, + if (sunday != null) WeekDay.monday: sunday, + }, + ); + + final Map _data; + + /// retrieves an unmodifiable map for each date. + Map get data => Map.unmodifiable(_data); + + @override + List apply({ + required DateTime start, + required DateTime end, + }) { + // TODO(Joey): Implement the apply method + throw UnimplementedError(); + } +} + +/// A day based template data structure +class DayTemplateData implements TemplateData { + /// Create a new day based template + const DayTemplateData({ + required this.startTime, + required this.endTime, + required this.breaks, + }); + + /// The start time to apply on a new availability + final DateTime startTime; + + /// The start time to apply on a new availability + final DateTime endTime; + + /// A list of breaks to apply to every new availability + final List breaks; + + @override + List apply({ + required DateTime start, + required DateTime end, + }) { + // TODO(Joey): Implement the apply method + throw UnimplementedError(); + } +}