Skip to content

Commit

Permalink
Merge pull request #13 from markhuot/entryquery-cleanup-assets-and-te…
Browse files Browse the repository at this point in the history
…mplates

entry queries and assets all use templates now
  • Loading branch information
markhuot authored Nov 29, 2023
2 parents abf3117 + 1d07493 commit 9bc6b2e
Show file tree
Hide file tree
Showing 27 changed files with 252 additions and 164 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,7 @@ jobs:
uses: actions/cache@v3
with:
path: seed.sql
key: ${{ runner.os }}-seed-${{ hashFiles('config/project/project.yaml') }}
restore-keys: |
${{ runner.os }}-seed-
key: ${{ runner.os }}-seed-${{ hashFiles('config/project/project.yaml', 'src/migrations/*.php') }}
- name: Install Craft
if: steps.database-cache.outputs.cache-hit != 'true'
run: |
Expand All @@ -160,4 +158,4 @@ jobs:
- name: Install plugins
run: ./bin/post-install.sh
- name: Run test suite
run: ./vendor/bin/pest
run: ./vendor/bin/pest -vvv
2 changes: 1 addition & 1 deletion src/actions/GetComponentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function byType(string $type): ComponentType
$fqcn = $className;
}

if ($fqcn) {
if (! empty($fqcn)) {
return Craft::$container->get($fqcn, ['context' => $this->context]);
}

Expand Down
5 changes: 2 additions & 3 deletions src/assetbundles/KeystoneAssetBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ public function init()
$this->depends = [];

$this->js = [
'components/create.js',
'components/edit.js',
'components/drag.js',
'lib/alpine.min.js',
'lib/axios.min.js',
'components/alpine.js',
'components/post.js',
'components/slideout.js',
];

$this->css = [
Expand Down
5 changes: 4 additions & 1 deletion src/base/ComponentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ public function render(array $variables = []): string

abstract public function getTemplatePath(): string;

public function getSlotDefinitions()
/**
* @return Collection<SlotDefinition>
*/
public function getSlotDefinitions(): Collection
{
return $this->getSchema()[1];
}
Expand Down
14 changes: 14 additions & 0 deletions src/base/SlotDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

class SlotDefinition
{
protected bool $collapsed = false;

public function __construct(
protected ?Component $component = null,
protected ?string $name = null,
Expand Down Expand Up @@ -43,6 +45,18 @@ public function defaults(array $componentConfig): self
return $this;
}

public function collapsed(bool $collapsed = true): self
{
$this->collapsed = $collapsed;

return $this;
}

public function isCollapsed(): bool
{
return $this->collapsed;
}

public function allows(string $type): bool
{
if (! empty($this->whitelist)) {
Expand Down
23 changes: 22 additions & 1 deletion src/controllers/ComponentsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ public function actionUpdate()

(new EditComponentData)->handle($component, $fields);

return $this->asSuccess('Component saved');
return $this->asSuccess('Component saved', [
'fieldHtml' => $component->getElement()->getFieldHtml($component->getField()),
]);
}

public function actionDelete()
Expand All @@ -105,4 +107,23 @@ public function actionMove()
'fieldHtml' => $data->getTargetElement()->getFieldHtml($data->getTargetField()),
]);
}

public function actionToggleDisclosure()
{
/** @var Component $component */
$component = $this->request->getQueryParamObjectOrFail(Component::class);
$defns = $component->getType()->getSlotDefinitions();
$defaultState = $defns->every(fn ($d) => $d->isCollapsed()) ? 'closed' : 'open';
$state = $component->disclosure->state ?? $defaultState;
$newState = $state === 'open' ? 'closed' : 'open';

if ($newState === $defaultState) {
$component->disclosure->delete();
} else {
$component->disclosure->state = $newState;
$component->disclosure->save();
}

return $this->asSuccess();
}
}
2 changes: 2 additions & 0 deletions src/db/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ class Table
const COMPONENTS = '{{%keystone_components}}';

const COMPONENT_DATA = '{{%keystone_component_data}}';

const COMPONENT_DISCLOSURES = '{{%keystone_component_disclosure}}';
}
2 changes: 1 addition & 1 deletion src/fields/Keystone.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ protected function inputHtml(mixed $value, ElementInterface $element = null): st
return Craft::$app->getView()->renderTemplate('keystone/field', [
'element' => $element,
'field' => $this,
'component' => $this->getFragment($element),
'component' => $this->getFragment($element)->withDisclosures(),
'getComponentTypes' => new GetComponentType,
]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/listeners/RegisterDefaultComponentTypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ class RegisterDefaultComponentTypes
public function handle(RegisterComponentTypes $event): void
{
$event->registerTwigTemplate('keystone/asset', 'cp:keystone/components/asset.twig');
$event->registerTwigTemplate('keystone/elementquery', 'cp:keystone/components/elementquery.twig');
$event->registerTwigTemplate('keystone/entry', 'cp:keystone/components/entry.twig');
$event->registerTwigTemplate('keystone/entryquery', 'cp:keystone/components/entryquery.twig');
$event->registerTwigTemplate('keystone/fragment', 'cp:keystone/components/fragment.twig');
$event->registerTwigTemplate('keystone/heading', 'cp:keystone/components/heading.twig');
$event->registerTwigTemplate('keystone/icon', 'cp:keystone/components/icon.twig');
Expand Down
13 changes: 13 additions & 0 deletions src/migrations/Install.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,29 @@ public function safeUp()
'uid' => $this->uid(),
]);

$this->createTable(Table::COMPONENT_DISCLOSURES, [
'id' => $this->primaryKey(),
'userId' => $this->integer(),
'componentId' => $this->integer(),
'state' => $this->enum('state', ['open', 'closed']),
'dateCreated' => $this->dateTime()->notNull(),
'dateUpdated' => $this->dateTime()->notNull(),
'uid' => $this->uid(),
]);

$this->createIndex(null, Table::COMPONENTS, ['id', 'elementId']);
$this->addForeignKey(null, Table::COMPONENTS, ['elementId'], \craft\db\Table::ELEMENTS, ['id'], 'CASCADE', null);
$this->addForeignKey(null, Table::COMPONENTS, ['fieldId'], \craft\db\Table::FIELDS, ['id'], 'CASCADE', null);
$this->addForeignKey(null, Table::COMPONENTS, ['dataId'], Table::COMPONENT_DATA, ['id'], 'CASCADE', null);
$this->addForeignKey(null, Table::COMPONENT_DISCLOSURES, ['userId'], \craft\db\Table::USERS, ['id'], 'CASCADE', null);
$this->addForeignKey(null, Table::COMPONENT_DISCLOSURES, ['componentId'], Table::COMPONENTS, ['id'], 'CASCADE', null);

return true;
}

public function safeDown()
{
$this->dropTableIfExists(Table::COMPONENT_DISCLOSURES);
$this->dropTableIfExists(Table::COMPONENTS);
$this->dropTableIfExists(Table::COMPONENT_DATA);

Expand Down
46 changes: 41 additions & 5 deletions src/models/Component.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class Component extends ActiveRecord

protected ?ComponentType $_type = null;

protected bool $withDisclosures = false;

public static function factory(): \markhuot\keystone\factories\Component
{
return new \markhuot\keystone\factories\Component;
Expand All @@ -73,6 +75,33 @@ public function getData(): ActiveQuery
return $this->hasOne(ComponentData::class, ['id' => 'dataId']);
}

public function getDisclosure(): ActiveQuery
{
$query = $this->hasOne(ComponentDisclosure::class, ['componentId' => 'id']);

if (app()->getUser()->getIdentity()) {
$query->where(['userId' => app()->getUser()->getIdentity()->id]);
}

return $query;
}

public function withDisclosures(bool $withDisclosures = true): self
{
$this->withDisclosures = $withDisclosures;

return $this;
}

public function isCollapsed(): bool
{
$shouldBeClosed = $this->getType()->getSlotDefinitions()->every(fn ($defn) => $defn->isCollapsed());
$notForcedOpen = $this->disclosure->state !== 'open';
$forcedClosed = $this->disclosure->state == 'closed';

return ($shouldBeClosed && $notForcedOpen) || $forcedClosed;
}

/**
* @return array<string>
*/
Expand Down Expand Up @@ -124,6 +153,13 @@ public function __get($name)
$value = $data;
}

if ($name === 'disclosure' && $value === null) {
$this->populateRelation($name, $data = new ComponentDisclosure);
$data->userId = app()->getUser()->getIdentity()->id;
$data->componentId = $this->id;
$value = $data;
}

if ($name === 'data' && $value instanceof ComponentData) {
$value->setNormalizer((new NormalizeFieldDataForComponent($this))->handle(...));
}
Expand Down Expand Up @@ -286,20 +322,20 @@ public function getSlot(string $name = null): SlotCollection

if ($this->slotted === null && $this->elementId && $this->fieldId) {
$components = Component::find()
->with('data')
->with(array_filter(['data', $this->withDisclosures ? 'disclosure' : null]))
->where(['and',
['elementId' => $this->elementId],
['fieldId' => $this->fieldId],
new OrCondition(array_filter([
! $this->getChildPath() ? ['path' => null] : null,
['like', 'path', $this->getChildPath().'%', false],
])),

// this is intentionally left out. We don't want to limit our query by slot name
// because children of this component may not share the same name. We need to pull
// all children out of the database and then the slot name filtering happens below
// before being returned.
// ['slot' => $name],
new OrCondition(array_filter([
! $this->getChildPath() ? ['path' => null] : null,
['like', 'path', $this->getChildPath().'%', false],
])),
])
->orderBy('sortOrder')
->collect();
Expand Down
14 changes: 14 additions & 0 deletions src/models/ComponentDisclosure.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace markhuot\keystone\models;

use markhuot\keystone\db\ActiveRecord;
use markhuot\keystone\db\Table;

class ComponentDisclosure extends ActiveRecord
{
public static function tableName()
{
return Table::COMPONENT_DISCLOSURES;
}
}
67 changes: 0 additions & 67 deletions src/resources/components/create.js

This file was deleted.

57 changes: 0 additions & 57 deletions src/resources/components/edit.js

This file was deleted.

Loading

0 comments on commit 9bc6b2e

Please sign in to comment.