Line data Source code
1 : part of apptive_grid_model; 2 : 3 : /// A Uri representation used for performing Form based Api Calls 4 : /// 5 : /// FormUris can come from different sources. 6 : /// 7 : /// Depending on your use case you should use a different constructor 8 : /// 9 : /// [FormUri.fromUri] is best used if you have a URI Link to a Form but don't know if it's a redirect Link or a direct Link to a Form 10 : /// 11 : /// [RedirectFormUri] should be used if you accessed a Form via a Redirect Link e.g. https://app.apptivegrid.de/api/r/609bd6f89fcca3c4c77e70fa 12 : /// [DirectFormUri] should be used if accessed 13 : abstract class FormUri extends ApptiveGridUri { 14 4 : FormUri._(); 15 : 16 : /// Creates a FormUri based on a [uri] 17 : /// [uri] must match either: 18 : /// /api/(r|a)/(\w+)\b for [RedirectFormUri] 19 : /// or 20 : /// /api/users/(\w+)/spaces/(\w+)/grids/(\w+)/forms/(\w+)\b for [DirectFormUri] 21 : /// 22 : /// throws an [ArgumentError] if [uri] can't be matched against against the above regexes 23 2 : factory FormUri.fromUri(String uri) { 24 4 : if (RegExp(DirectFormUri._regex).hasMatch(uri)) { 25 2 : return DirectFormUri.fromUri(uri); 26 : } 27 4 : if (RegExp(RedirectFormUri._regex).hasMatch(uri)) { 28 2 : return RedirectFormUri.fromUri(uri); 29 : } 30 2 : throw ArgumentError('Could not parse FormUri $uri'); 31 : } 32 : 33 : /// Returns the uriString used for Api Calls using this FormUri 34 : @override 35 : String get uriString; 36 : 37 : /// Indicates whether or not a call to this Form will require Authentication 38 : /// 39 : /// return [false] for [RedirectFormUri] 40 : /// return [true] for [DirectFormUri] 41 : bool get needsAuthorization; 42 : } 43 : 44 : /// A FormUri for a Form represented by a redirect Link 45 : class RedirectFormUri extends FormUri { 46 : /// Create a FormUri accessed via a redirect Link from the ApptiveGrid UI Console 47 : /// for https://app.apptivegrid.de/api/r/609bd6f89fcca3c4c77e70fa `609bd6f89fcca3c4c77e70fa` would be [components] 48 3 : RedirectFormUri({ 49 : required this.components, 50 3 : }) : super._(); 51 : 52 : /// Creates a FormUri based on a [uri] 53 : /// [uri] must match: 54 : /// /api/(r|a)/(\w+)\b 55 3 : factory RedirectFormUri.fromUri(String uri) { 56 6 : final matches = RegExp(_regex).allMatches(uri); 57 12 : if (matches.isEmpty || matches.elementAt(0).groupCount < 2) { 58 2 : throw ArgumentError('Could not parse FormUri $uri'); 59 : } 60 3 : final match = matches.elementAt(0); 61 9 : return RedirectFormUri(components: match.group(2)!.split('/')); 62 : } 63 : 64 : static const _regex = r'/api/(r|a)/((\w+/?)+)'; 65 : 66 : /// Id this is representing 67 : /// for https://app.apptivegrid.de/api/r/609bd6f89fcca3c4c77e70fa `609bd6f89fcca3c4c77e70fa` would be [components] 68 : final List<String> components; 69 : 70 3 : @override 71 9 : String get uriString => '/api/a/${components.join('/')}'; 72 : 73 1 : @override 74 : bool get needsAuthorization => false; 75 : 76 2 : @override 77 : String toString() { 78 4 : return 'RedirectFormUri(form: $components)'; 79 : } 80 : 81 2 : @override 82 : bool operator ==(Object other) { 83 2 : return other is RedirectFormUri && 84 6 : f.listEquals(components, other.components); 85 : } 86 : 87 2 : @override 88 4 : int get hashCode => toString().hashCode; 89 : } 90 : 91 : /// A FormUri for a Form represented by a direct Link 92 : class DirectFormUri extends FormUri { 93 : /// Create a FormUri with known attributes for [user], [space], [grid], [form] 94 3 : DirectFormUri({ 95 : required this.user, 96 : required this.space, 97 : required this.grid, 98 : required this.form, 99 : this.entity, 100 3 : }) : super._(); 101 : 102 : /// Creates a FormUri based on a [uri] 103 : /// Creates a FormUri based on a [uri] 104 : /// [uri] must match: 105 : /// /api/users/(\w+)/spaces/(\w+)/grids/(\w+)/forms/(\w+)\b 106 3 : factory DirectFormUri.fromUri(String uri) { 107 3 : final parsed = Uri.parse(uri); 108 9 : final matches = RegExp(_regex).allMatches(parsed.path); 109 12 : if (matches.isEmpty || matches.elementAt(0).groupCount != 4) { 110 2 : throw ArgumentError('Could not parse FormUri $uri'); 111 : } 112 : 113 3 : final match = matches.elementAt(0); 114 : EntityUri? entity; 115 6 : if (parsed.queryParameters['uri'] != null) { 116 3 : entity = EntityUri.fromUri(parsed.queryParameters['uri']!); 117 : } 118 3 : return DirectFormUri( 119 3 : user: match.group(1)!, 120 3 : space: match.group(2)!, 121 3 : grid: match.group(3)!, 122 3 : form: match.group(4)!, 123 : entity: entity, 124 : ); 125 : } 126 : 127 : static const _regex = 128 : r'/api/users/(\w+)/spaces/(\w+)/grids/(\w+)/forms/(\w+)\b'; 129 : 130 : /// Id of the User that owns this Grid 131 : final String user; 132 : 133 : /// Id of the Space this Grid is in 134 : final String space; 135 : 136 : /// Id of the Grid this is in 137 : final String grid; 138 : 139 : /// Id of the Form this [FormUri] is representing 140 : final String form; 141 : 142 : /// Optional [EntityUri] leading to a pre-filled form 143 : final EntityUri? entity; 144 : 145 1 : @override 146 : bool get needsAuthorization => true; 147 : 148 3 : @override 149 : String get uriString { 150 : var entityAppendix = ''; 151 3 : if (entity != null) { 152 3 : entityAppendix = '?uri=${entity!.uriString}'; 153 : } 154 15 : return '/api/users/$user/spaces/$space/grids/$grid/forms/$form$entityAppendix'; 155 : } 156 : 157 : /// Returns a FormUri pointing to a Form prefilled with values for a certain [EntityUri] 158 1 : FormUri forEntity({ 159 : required EntityUri entity, 160 : }) { 161 1 : return DirectFormUri( 162 1 : user: user, 163 1 : space: space, 164 1 : grid: grid, 165 1 : form: form, 166 : entity: entity, 167 : ); 168 : } 169 : 170 2 : @override 171 : String toString() { 172 12 : return 'DirectFormUri(user: $user, space: $space, grid: $grid, form: $form, entity: $entity)'; 173 : } 174 : 175 2 : @override 176 : bool operator ==(Object other) { 177 2 : return other is DirectFormUri && 178 6 : grid == other.grid && 179 6 : user == other.user && 180 6 : space == other.space && 181 6 : form == other.form && 182 6 : entity == other.entity; 183 : } 184 : 185 2 : @override 186 4 : int get hashCode => toString().hashCode; 187 : }