Skip to content

Commit

Permalink
Merge pull request #15 from RhysLees/main
Browse files Browse the repository at this point in the history
Allow steps to be limited to specific classes
  • Loading branch information
freekmurze authored Sep 24, 2022
2 parents 5e204d3 + f8a02ec commit bc0de35
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 5 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,41 @@ Onboard::addStep('Excluded Step')
});
```

Limiting steps to a specific class:

```php
Onboard::addStep('Limited Step', User::class)
->link('/post/create');

// or

Onboard::addStep('Limited Step', 'App\Models\User')
->link('/post/create');
```

When using limited steps, steps that are not limited will be available to all classes. For example:

```php
// Defining User steps
Onboard::addStep('Limited User Step', User::class)
->link('/post/create');

// Defining Team steps
Onboard::addStep('Limited Team Step', Team::class)
->link('/post/create');

// Defining a step that is available to all classes
Onboard::addStep('Normal Step')
->link('/post/create');
```

The above will result in 1 step being available to all classes, and 2 steps being available to the `User` and `Team` classes:

`Other` classes will only see the `Normal Step`.
`User` classes will both see the `Normal Step` and `Limited User Step`.
`Team` classes will both see the `Normal Step` and `Limited Team Step`.


Definining custom attributes and accessing them:

```php
Expand Down
2 changes: 1 addition & 1 deletion src/Facades/Onboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Spatie\Onboard\OnboardingSteps;

/**
* @method OnboardingStep addStep(string $title)
* @method OnboardingStep addStep(string $title, string $model = null)
* @method Collection<OnboardingStep> steps(Onboardable $model)
*/
class Onboard extends Facade
Expand Down
26 changes: 22 additions & 4 deletions src/OnboardingSteps.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,35 @@ class OnboardingSteps
/** @var array<OnboardingStep> */
protected array $steps = [];

public function addStep(string $title): OnboardingStep
public function addStep(string $title, string $model = null): OnboardingStep
{
$this->steps[] = $step = new OnboardingStep($title);
$step = new OnboardingStep($title);

return $step;
if ($model && new $model() instanceof Onboardable) {
return $this->steps[$model][] = $step;
}

return $this->steps['default'][] = $step;
}

public function steps(Onboardable $model): Collection
{
return collect($this->steps)
return collect($this->getStepsArray($model))
->map(fn (OnboardingStep $step) => $step->initiate($model))
->filter(fn (OnboardingStep $step) => $step->notExcluded());
}

private function getStepsArray(Onboardable $model): array
{
$key = get_class($model);

if (key_exists($key, $this->steps)) {
return array_merge(
$this->steps[$key],
$this->steps['default'] ?? []
);
}

return $this->steps['default'] ?? [];
}
}
90 changes: 90 additions & 0 deletions tests/OnboardTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@

use Spatie\Onboard\OnboardingManager;
use Spatie\Onboard\OnboardingSteps;
use Spatie\Onboard\Tests\Team;
use Spatie\Onboard\Tests\User;

beforeEach(function () {
$this->user = new User();
$this->team = new Team();
});

test('steps can be defined and configured', function () {
Expand All @@ -21,6 +23,35 @@
});

$this->assertEquals(1, $onboardingSteps->steps(new User())->count());
$this->assertEquals(1, $onboardingSteps->steps(new Team())->count());

$userStep = $onboardingSteps->steps(new User())->first();
$teamStep = $onboardingSteps->steps(new Team())->first();

expect($userStep->link)->toBe('/some/url')
->and($userStep->cta)->toBe('Test This!')
->and($userStep->title)->toBe('Test Step')
->and($userStep->another)->toBe('attribute');

expect($teamStep->link)->toBe('/some/url')
->and($teamStep->cta)->toBe('Test This!')
->and($teamStep->title)->toBe('Test Step')
->and($teamStep->another)->toBe('attribute');
});

test('limited steps can be defined and configured', function () {
$onboardingSteps = new OnboardingSteps();

$onboardingSteps->addStep('Test Step', User::class)
->link('/some/url')
->cta('Test This!')
->attributes(['another' => 'attribute'])
->completeIf(function () {
return true;
});

$this->assertEquals(1, $onboardingSteps->steps(new User())->count());
$this->assertEquals(0, $onboardingSteps->steps(new Team())->count());

$step = $onboardingSteps->steps(new User())->first();

Expand All @@ -30,6 +61,40 @@
->and($step->another)->toBe('attribute');
});

test('limited steps can be defined with normal steps', function () {
$onboardingSteps = new OnboardingSteps();

$onboardingSteps->addStep('Test Step', User::class);

$onboardingSteps->addStep('Test Step Normal');

$this->assertEquals(2, $onboardingSteps->steps(new User())->count());
});

test('multipe limited step models can be defined', function () {
$onboardingSteps = new OnboardingSteps();

$onboardingSteps->addStep('Test Step', User::class);

$onboardingSteps->addStep('Test Step Team', Team::class);

$this->assertEquals(1, $onboardingSteps->steps(new User())->count());
$this->assertEquals(1, $onboardingSteps->steps(new Team())->count());
});

test('multipe limited step models can be defined with normal steps', function () {
$onboardingSteps = new OnboardingSteps();

$onboardingSteps->addStep('Test Step', User::class);

$onboardingSteps->addStep('Test Step Normal', Team::class);

$onboardingSteps->addStep('Test Step Normal');

$this->assertEquals(2, $onboardingSteps->steps(new User())->count());
$this->assertEquals(2, $onboardingSteps->steps(new Team())->count());
});

test('is in progress when all steps are incomplete', function () {
$onboardingSteps = new OnboardingSteps();
$onboardingSteps->addStep('Test Step');
Expand Down Expand Up @@ -62,6 +127,31 @@
->and($onboarding->inProgress())->toBeFalse();
});

test('is finished when all steps are complete for limited models steps', function () {
$onboardingSteps = new OnboardingSteps();
$onboardingSteps->addStep('Test Step', User::class)
->completeIf(function () {
return true;
});
$onboardingSteps->addStep('Test Step', Team::class)
->completeIf(function () {
return false;
});

$onboardingSteps->addStep('Excluded Step')
->excludeIf(function () {
return true;
})
->completeIf(function () {
return false;
});

$onboarding = new OnboardingManager($this->user, $onboardingSteps);

expect($onboarding->finished())->toBeTrue()
->and($onboarding->inProgress())->toBeFalse();
});

test('it returns the correct next unfinished step', function () {
$onboardingSteps = new OnboardingSteps();
$onboardingSteps->addStep('Step 1')
Expand Down
12 changes: 12 additions & 0 deletions tests/Team.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Spatie\Onboard\Tests;

use Illuminate\Database\Eloquent\Model;
use Spatie\Onboard\Concerns\GetsOnboarded;
use Spatie\Onboard\Concerns\Onboardable;

class Team extends Model implements Onboardable
{
use GetsOnboarded;
}

0 comments on commit bc0de35

Please sign in to comment.