44
55namespace Relaticle \Flowforge \Adapters ;
66
7+ use DB ;
78use Illuminate \Database \Eloquent \Model ;
89use Illuminate \Support \Collection ;
910use Livewire \Wireable ;
@@ -46,6 +47,13 @@ class DefaultKanbanAdapter implements IKanbanAdapter, Wireable
4647 */
4748 protected array $ cardAttributes = [];
4849
50+ /**
51+ * The order field for the model.
52+ *
53+ * @var string|null
54+ */
55+ protected ?string $ orderField = null ;
56+
4957 /**
5058 * The model class for the adapter.
5159 *
@@ -62,21 +70,24 @@ class DefaultKanbanAdapter implements IKanbanAdapter, Wireable
6270 * @param string $titleAttribute The title attribute
6371 * @param string|null $descriptionAttribute The description attribute
6472 * @param array<string> $cardAttributes The card attributes
73+ * @param string|null $orderField The order field
6574 */
6675 public function __construct (
6776 string $ modelClass ,
6877 string $ statusField ,
6978 array $ statusValues ,
7079 string $ titleAttribute ,
7180 ?string $ descriptionAttribute = null ,
72- array $ cardAttributes = []
81+ array $ cardAttributes = [],
82+ ?string $ orderField = null
7383 ) {
7484 $ this ->modelClass = $ modelClass ;
7585 $ this ->statusField = $ statusField ;
7686 $ this ->statusValues = $ statusValues ;
7787 $ this ->titleAttribute = $ titleAttribute ;
7888 $ this ->descriptionAttribute = $ descriptionAttribute ;
7989 $ this ->cardAttributes = $ cardAttributes ;
90+ $ this ->orderField = $ orderField ;
8091 }
8192
8293 /**
@@ -151,6 +162,16 @@ public function getCardAttributes(): array
151162 return $ this ->cardAttributes ;
152163 }
153164
165+ /**
166+ * Get the order field for the model.
167+ *
168+ * @return string|null
169+ */
170+ public function getOrderField (): ?string
171+ {
172+ return $ this ->orderField ;
173+ }
174+
154175 /**
155176 * Get the items for all statuses.
156177 *
@@ -171,7 +192,14 @@ public function getItems(): Collection
171192 public function getItemsForStatus (string $ status ): Collection
172193 {
173194 $ modelClass = $ this ->getModel ();
174- return $ modelClass ::where ($ this ->getStatusField (), $ status )->get ();
195+ $ query = $ modelClass ::where ($ this ->getStatusField (), $ status );
196+
197+ // Add ordering if order field is set
198+ if ($ this ->getOrderField ()) {
199+ $ query ->orderBy ($ this ->getOrderField ());
200+ }
201+
202+ return $ query ->get ();
175203 }
176204
177205 /**
@@ -187,6 +215,41 @@ public function updateStatus(Model $model, string $status): bool
187215 return $ model ->save ();
188216 }
189217
218+ /**
219+ * Update the order of a model.
220+ *
221+ * @param string|int $columnId
222+ * @param array $cards
223+ * @return bool
224+ * @throws \Throwable
225+ */
226+ public function updateColumnCards (string |int $ columnId , array $ cards ): bool
227+ {
228+ if (!$ this ->getOrderField ()) {
229+ return false ;
230+ }
231+
232+ $ model = app ($ this ->getModel ());
233+
234+ // Validate column ID exists in status values
235+ if (!array_key_exists ((string )$ columnId , $ this ->getStatusValues ())) {
236+ return false ;
237+ }
238+
239+ return DB ::transaction (function () use ($ model , $ columnId , $ cards ) {
240+ foreach ($ cards as $ index => $ id ) {
241+ $ model ->newQuery ()
242+ ->where ($ model ->getQualifiedKeyName (), $ id )
243+ ->update ([
244+ $ this ->getStatusField () => $ columnId ,
245+ $ this ->getOrderField () => $ index ,
246+ ]);
247+ }
248+
249+ return true ;
250+ });
251+ }
252+
190253 /**
191254 * Create a new card with the given attributes.
192255 *
@@ -202,6 +265,15 @@ public function createCard(array $attributes): ?Model
202265 $ status = $ attributes [$ this ->getStatusField ()] ?? array_key_first ($ this ->getStatusValues ());
203266 $ card ->{$ this ->getStatusField ()} = $ status ;
204267
268+ // Set order if the field exists
269+ if ($ this ->getOrderField ()) {
270+ // Set the highest order by default (add to the end of the column)
271+ $ maxOrder = $ modelClass ::where ($ this ->getStatusField (), $ status )
272+ ->max ($ this ->getOrderField ()) ?? 0 ;
273+
274+ $ card ->{$ this ->getOrderField ()} = $ maxOrder + 1 ;
275+ }
276+
205277 // Set title
206278 if (isset ($ attributes [$ this ->getTitleAttribute ()])) {
207279 $ card ->{$ this ->getTitleAttribute ()} = $ attributes [$ this ->getTitleAttribute ()];
@@ -281,6 +353,7 @@ public function toLivewire(): array
281353 'titleAttribute ' => $ this ->getTitleAttribute (),
282354 'descriptionAttribute ' => $ this ->getDescriptionAttribute (),
283355 'cardAttributes ' => $ this ->getCardAttributes (),
356+ 'orderField ' => $ this ->getOrderField (),
284357 ];
285358 }
286359
@@ -298,7 +371,8 @@ public static function fromLivewire($value)
298371 $ value ['statusValues ' ],
299372 $ value ['titleAttribute ' ],
300373 $ value ['descriptionAttribute ' ] ?? null ,
301- $ value ['cardAttributes ' ] ?? []
374+ $ value ['cardAttributes ' ] ?? [],
375+ $ value ['orderField ' ] ?? null
302376 );
303377 }
304378}
0 commit comments