Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

* [PR-45](https://github.com/itk-dev/itk-projects/pull/45)
Remove the "Strategies and plans" field. Update Summary help text to now ask
for strategy and plans.
* [PR-42](https://github.com/itk-dev/itk-projects/pull/42)
Describe what ITK counts as a project: a callout on the create page, a
"What counts as a project?" dialog on the project list, and a tour step.
Expand Down
4 changes: 2 additions & 2 deletions assets/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ function initCreatableSelect(selector, poolKey, transform) {
});
}

// Free-tagging term fields (strategies, tags) capitalise new
// entries; partners keep the typed name as-is.
// Free-tagging term fields (tags) capitalise new entries; partners keep
// the typed name as-is.
function initTermSelect() {
initCreatableSelect("[data-term-select]", "termPool", capitalize);
}
Expand Down
38 changes: 38 additions & 0 deletions migrations/Version20261001080000.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* The "Strategies and plans" free-tagging field is gone; strategy and plans
* are now part of what the Summary asks for.
*/
final class Version20261001080000 extends AbstractMigration
{
public function getDescription(): string
{
return 'Remove the strategy vocabulary: drop project_strategy and its terms.';
}

public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE project_strategy DROP FOREIGN KEY `FK_2908CE36166D1F9C`');
$this->addSql('ALTER TABLE project_strategy DROP FOREIGN KEY `FK_2908CE36E2C35FC`');
$this->addSql('DROP TABLE project_strategy');
// The Vocabulary enum no longer has a strategy case, so leftover rows
// would fail to hydrate.
$this->addSql("DELETE FROM term WHERE vocabulary = 'strategy'");
}

public function down(Schema $schema): void
{
// Recreates the empty join table only; the deleted terms are not restored.
$this->addSql('CREATE TABLE project_strategy (project_id BINARY(16) NOT NULL, term_id BINARY(16) NOT NULL, INDEX IDX_2908CE36166D1F9C (project_id), INDEX IDX_2908CE36E2C35FC (term_id), PRIMARY KEY (project_id, term_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = \'\' ');
$this->addSql('ALTER TABLE project_strategy ADD CONSTRAINT `FK_2908CE36166D1F9C` FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE project_strategy ADD CONSTRAINT `FK_2908CE36E2C35FC` FOREIGN KEY (term_id) REFERENCES term (id) ON DELETE CASCADE');
}
}
2 changes: 0 additions & 2 deletions src/Controller/ProjectController.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ public function export(Request $request, ProjectRepository $projects, Translator
$translator->trans('project.endorsement_author'),
$translator->trans('project.budget'),
$translator->trans('project.funding'),
$translator->trans('project.strategies'),
$translator->trans('project.tags'),
$translator->trans('project.time_period_start'),
$translator->trans('project.time_period_end'),
Expand All @@ -99,7 +98,6 @@ public function export(Request $request, ProjectRepository $projects, Translator
$translate($row->getEndorsementAuthor()),
$row->getBudget(),
implode(', ', array_map($translate, $row->getFunding())),
$names($row->getStrategies()),
$names($row->getTags()),
$row->getTimePeriodStart()?->format('Y-m-d'),
$row->getTimePeriodEnd()?->format('Y-m-d'),
Expand Down
5 changes: 0 additions & 5 deletions src/DataFixtures/AppFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
class AppFixtures extends Fixture
{
private const array TAGS = ['Bæredygtighed', 'Borgerinddragelse', 'Innovation', 'Sundhed', 'Klima', 'Mobilitet', 'Data', 'Tryghed', 'Læring', 'Fællesskab'];
private const array STRATEGIES = ['Klimaplan 2030', 'Erhvervsplan', 'Børn- og ungepolitik', 'Mobilitetsplan', 'Digitaliseringsstrategi', 'Sundhedspolitik'];
private const array DEPARTMENTS = ['ITK Development', 'CFIA', 'Aarhus CityLab', 'Stab', 'OS2', 'AI Lab', 'IOT Lab', 'GTM', 'Fut Lab'];
private const array PARTNERS = ['Aarhus Universitet', 'VIA University College', 'Alexandra Instituttet', 'Teknologisk Institut', 'Region Midtjylland', 'Erhverv Aarhus', 'Danmarks Tekniske Universitet', 'Aarhus Vand', 'AffaldVarme Aarhus', 'Dansk Industri'];
private const array AREAS = ['Klima og miljø', 'Mobilitet', 'Velfærd', 'Kultur og fritid', 'Uddannelse', 'Erhverv', 'Digitalisering', 'Byudvikling'];
Expand Down Expand Up @@ -60,7 +59,6 @@ public function load(ObjectManager $manager): void
$users = [$admin, $editor];

$tags = $this->makeTerms($manager, self::TAGS, Vocabulary::Tag);
$strategies = $this->makeTerms($manager, self::STRATEGIES, Vocabulary::Strategy);

$departments = [];
foreach (self::DEPARTMENTS as $name) {
Expand Down Expand Up @@ -181,9 +179,6 @@ public function load(ObjectManager $manager): void
foreach (\array_slice($this->shuffleCopy($tags), 0, mt_rand(1, 4)) as $term) {
$project->addTag($term);
}
foreach (\array_slice($this->shuffleCopy($strategies), 0, mt_rand(0, 2)) as $term) {
$project->addStrategy($term);
}
foreach (\array_slice($this->shuffleCopy($contacts), 0, mt_rand(1, 3)) as $contact) {
$project->addContact($contact);
}
Expand Down
41 changes: 1 addition & 40 deletions src/Entity/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,14 @@ class Project extends AbstractEntity
#[ORM\JoinColumn(onDelete: 'SET NULL')]
private ?Area $area = null;

/** A few lines summing up the project's purpose and content. */
/** A few lines summing up the project's purpose, content, strategy and plans. */
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $summary = null;

/** The fuller account: why the project is done and what it is anchored in. */
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $description = null;

/** @var Collection<int, Term> */
#[ORM\ManyToMany(targetEntity: Term::class, cascade: ['persist'])]
#[ORM\JoinTable(name: 'project_strategy')]
private Collection $strategies;

/**
* What kind of thing the project is ("Projekt", "Drift", …). A project can be
* several at once, e.g. a pilot that is also operations.
Expand Down Expand Up @@ -141,7 +136,6 @@ public function __construct()
parent::__construct();
$this->organizationalAnchoring = new ArrayCollection();
$this->types = new ArrayCollection();
$this->strategies = new ArrayCollection();
$this->contacts = new ArrayCollection();
$this->partners = new ArrayCollection();
$this->tags = new ArrayCollection();
Expand Down Expand Up @@ -207,39 +201,6 @@ public function setDescription(?string $description): static
return $this;
}

/** @return Collection<int, Term> */
public function getStrategies(): Collection
{
return $this->strategies;
}

public function addStrategy(Term $term): static
{
if (!$this->strategies->contains($term)) {
$this->strategies->add($term);
}

return $this;
}

public function removeStrategy(Term $term): static
{
$this->strategies->removeElement($term);

return $this;
}

/** @param iterable<Term> $terms */
public function setStrategies(iterable $terms): static
{
$this->strategies->clear();
foreach ($terms as $term) {
$this->addStrategy($term);
}

return $this;
}

/** @return Collection<int, ProjectType> */
public function getTypes(): Collection
{
Expand Down
1 change: 0 additions & 1 deletion src/Enum/Vocabulary.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
enum Vocabulary: string implements TranslatableEnum
{
case Tag = 'tag';
case Strategy = 'strategy';

public function labelKey(): string
{
Expand Down
6 changes: 0 additions & 6 deletions src/Form/ProjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'attr' => ['rows' => 8],
'help' => 'project.description_help',
])
->add('strategies', TermsTextType::class, [
'label' => 'project.strategies',
'vocabulary' => Vocabulary::Strategy,
'required' => false,
'help' => 'project.terms_help',
])
->add('types', EntityType::class, [
'label' => 'project.types',
'class' => ProjectTypeEntity::class,
Expand Down
3 changes: 1 addition & 2 deletions src/Repository/ProjectRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public function search(ProjectFilter $filter): QueryBuilder
// paginator's count stays correct.
sprintf('i.id IN (SELECT icrt.id FROM %s icrt JOIN icrt.createdBy cb WHERE LOWER(cb.name) LIKE :q)', Project::class),
sprintf('i.id IN (SELECT itag.id FROM %s itag JOIN itag.tags tg WHERE LOWER(tg.name) LIKE :q)', Project::class),
sprintf('i.id IN (SELECT istr.id FROM %s istr JOIN istr.strategies st WHERE LOWER(st.name) LIKE :q)', Project::class),
sprintf('i.id IN (SELECT icon.id FROM %s icon JOIN icon.contacts co WHERE LOWER(co.name) LIKE :q)', Project::class),
sprintf('i.id IN (SELECT ipar.id FROM %s ipar JOIN ipar.partners pa WHERE LOWER(pa.name) LIKE :q)', Project::class),
// Department, area and type are related entities searched by
Expand Down Expand Up @@ -147,7 +146,7 @@ public function findForExport(ProjectFilter $filter): array
return [];
}

foreach (['types', 'organizationalAnchoring', 'strategies', 'tags', 'contacts', 'partners'] as $association) {
foreach (['types', 'organizationalAnchoring', 'tags', 'contacts', 'partners'] as $association) {
$this->createQueryBuilder('i')
->addSelect('rel')
->leftJoin('i.'.$association, 'rel')
Expand Down
1 change: 0 additions & 1 deletion templates/project/_form.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
{{ form_row(form.organizationalAnchoring) }}
</div>
{{ form_row(form.statusAdditional) }}
{{ form_row(form.strategies) }}
{{ form_row(form.tags) }}
</div>

Expand Down
3 changes: 0 additions & 3 deletions templates/project/show.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,6 @@
{% else %}—{% endif %}
</dd>

<dt>{{ 'project.strategies'|trans }}</dt>
<dd>{{ h.term_list(project.strategies) }}</dd>

<dt>{{ 'project.tags'|trans }}</dt>
<dd>{{ h.term_list(project.tags) }}</dd>

Expand Down
6 changes: 3 additions & 3 deletions tests/Repository/TermRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ public function testFindOrCreateBuildsANewUnflushedTerm(): void
{
$name = 'BrandNewTag-'.uniqid();

$term = $this->repository->findOrCreate($name, Vocabulary::Strategy);
$term = $this->repository->findOrCreate($name, Vocabulary::Tag);

self::assertSame($name, $term->getName());
self::assertSame(Vocabulary::Strategy, $term->getVocabulary());
self::assertSame(Vocabulary::Tag, $term->getVocabulary());
self::assertCount(0, $this->repository->findBy(['name' => $name]), 'A freshly created term is not yet flushed to the database.');
}

public function testFindOrCreateCapitalisesANewTerm(): void
{
$term = $this->repository->findOrCreate('grøn omstilling '.uniqid(), Vocabulary::Strategy);
$term = $this->repository->findOrCreate('grøn omstilling '.uniqid(), Vocabulary::Tag);

self::assertSame('G', mb_substr((string) $term->getName(), 0, 1));
}
Expand Down
19 changes: 0 additions & 19 deletions tests/Unit/Entity/ProjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public function testDefaults(): void
self::assertSame([], $project->getLinks());
self::assertCount(0, $project->getOrganizationalAnchoring());
self::assertCount(0, $project->getTypes());
self::assertCount(0, $project->getStrategies());
self::assertCount(0, $project->getTags());
self::assertCount(0, $project->getContacts());
self::assertCount(0, $project->getPartners());
Expand Down Expand Up @@ -177,24 +176,6 @@ public function testTypeCollection(): void
self::assertCount(0, $project->getTypes());
}

public function testStrategyCollection(): void
{
$project = new Project();
$term = new Term(Vocabulary::Strategy);

$project->addStrategy($term);
$project->addStrategy($term);
self::assertCount(1, $project->getStrategies());

$project->removeStrategy($term);
self::assertCount(0, $project->getStrategies());

$project->setStrategies([new Term(Vocabulary::Strategy), new Term(Vocabulary::Strategy)]);
self::assertCount(2, $project->getStrategies());
$project->setStrategies([]);
self::assertCount(0, $project->getStrategies());
}

public function testTagCollection(): void
{
$project = new Project();
Expand Down
8 changes: 4 additions & 4 deletions tests/Unit/Entity/TermTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ public function testDefaultVocabularyIsTag(): void

public function testAccessors(): void
{
$term = (new Term(Vocabulary::Strategy))->setName('Klimaplan 2030');
$term = (new Term(Vocabulary::Tag))->setName('Klima');

self::assertSame('Klimaplan 2030', $term->getName());
self::assertSame(Vocabulary::Strategy, $term->getVocabulary());
self::assertSame('Klimaplan 2030', (string) $term);
self::assertSame('Klima', $term->getName());
self::assertSame(Vocabulary::Tag, $term->getVocabulary());
self::assertSame('Klima', (string) $term);

$term->setVocabulary(Vocabulary::Tag);
self::assertSame(Vocabulary::Tag, $term->getVocabulary());
Expand Down
4 changes: 1 addition & 3 deletions translations/messages.da.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,9 @@ project:
area: Område
area_help: Det tematiske område projektet hører under.
summary: Opsummering
summary_help: Kort opsummering af formål og indhold.
summary_help: Kort opsummering af formål, indhold, strategi og planer.
description: Beskrivelse
description_help: Hvorfor vi gør det, og hvad projektet har ophæng i.
strategies: Strategier og planer
types: Type
types_help: Fx projekt eller drift.
status: Status
Expand Down Expand Up @@ -420,4 +419,3 @@ enum:
external_partner: Ekstern partner
vocabulary:
tag: Tag
strategy: Strategi
4 changes: 1 addition & 3 deletions translations/messages.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,9 @@ project:
area: Area
area_help: The thematic area the project belongs to.
summary: Summary
summary_help: A brief summary of the purpose and content.
summary_help: A brief summary of the purpose, content, strategy and plans.
description: Description
description_help: Why we are doing it, and what the project is anchored in.
strategies: Strategies and plans
types: Type
types_help: E.g. project or operation.
status: Status
Expand Down Expand Up @@ -420,4 +419,3 @@ enum:
external_partner: External partner
vocabulary:
tag: Tag
strategy: Strategy
Loading