Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
d2ae1d09aa Bump the composer group across 1 directory with 9 updates
Bumps the composer group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [guzzlehttp/guzzle](https://github.com/guzzle/guzzle) | `7.10.3` | `7.12.1` |
| [laravel/framework](https://github.com/laravel/framework) | `12.60.2` | `12.61.1` |
| [phpoffice/phpspreadsheet](https://github.com/PHPOffice/PhpSpreadsheet) | `1.30.4` | `1.30.5` |
| [phpseclib/phpseclib](https://github.com/phpseclib/phpseclib) | `3.0.52` | `3.0.55` |
| [symfony/html-sanitizer](https://github.com/symfony/html-sanitizer) | `7.4.12` | `7.4.13` |



Updates `guzzlehttp/guzzle` from 7.10.3 to 7.12.1
- [Release notes](https://github.com/guzzle/guzzle/releases)
- [Changelog](https://github.com/guzzle/guzzle/blob/7.12/CHANGELOG.md)
- [Commits](https://github.com/guzzle/guzzle/compare/7.10.3...7.12.1)

Updates `laravel/framework` from 12.60.2 to 12.61.1
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/13.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v12.60.2...v12.61.1)

Updates `guzzlehttp/psr7` from 2.10.1 to 2.12.1
- [Release notes](https://github.com/guzzle/psr7/releases)
- [Changelog](https://github.com/guzzle/psr7/blob/2.12/CHANGELOG.md)
- [Commits](https://github.com/guzzle/psr7/compare/2.10.1...2.12.1)

Updates `phpoffice/phpspreadsheet` from 1.30.4 to 1.30.5
- [Release notes](https://github.com/PHPOffice/PhpSpreadsheet/releases)
- [Changelog](https://github.com/PHPOffice/PhpSpreadsheet/blob/1.30.5/CHANGELOG.md)
- [Commits](https://github.com/PHPOffice/PhpSpreadsheet/compare/1.30.4...1.30.5)

Updates `phpseclib/phpseclib` from 3.0.52 to 3.0.55
- [Release notes](https://github.com/phpseclib/phpseclib/releases)
- [Changelog](https://github.com/phpseclib/phpseclib/blob/master/CHANGELOG.md)
- [Commits](https://github.com/phpseclib/phpseclib/compare/3.0.52...3.0.55)

Updates `symfony/html-sanitizer` from 7.4.12 to 7.4.13
- [Release notes](https://github.com/symfony/html-sanitizer/releases)
- [Changelog](https://github.com/symfony/html-sanitizer/blob/8.2/CHANGELOG.md)
- [Commits](https://github.com/symfony/html-sanitizer/compare/v7.4.12...v7.4.13)

Updates `symfony/http-foundation` from 7.4.8 to 7.4.13
- [Release notes](https://github.com/symfony/http-foundation/releases)
- [Changelog](https://github.com/symfony/http-foundation/blob/8.2/CHANGELOG.md)
- [Commits](https://github.com/symfony/http-foundation/compare/v7.4.8...v7.4.13)

Updates `symfony/polyfill-intl-idn` from 1.37.0 to 1.38.1
- [Release notes](https://github.com/symfony/polyfill-intl-idn/releases)
- [Commits](https://github.com/symfony/polyfill-intl-idn/compare/v1.37.0...v1.38.1)

Updates `symfony/routing` from 7.4.12 to 7.4.13
- [Release notes](https://github.com/symfony/routing/releases)
- [Changelog](https://github.com/symfony/routing/blob/8.2/CHANGELOG.md)
- [Commits](https://github.com/symfony/routing/compare/v7.4.12...v7.4.13)

---
updated-dependencies:
- dependency-name: guzzlehttp/guzzle
  dependency-version: 7.12.1
  dependency-type: direct:production
  dependency-group: composer
- dependency-name: laravel/framework
  dependency-version: 12.61.1
  dependency-type: direct:production
  dependency-group: composer
- dependency-name: guzzlehttp/psr7
  dependency-version: 2.12.1
  dependency-type: indirect
  dependency-group: composer
- dependency-name: phpoffice/phpspreadsheet
  dependency-version: 1.30.5
  dependency-type: indirect
  dependency-group: composer
- dependency-name: phpseclib/phpseclib
  dependency-version: 3.0.55
  dependency-type: indirect
  dependency-group: composer
- dependency-name: symfony/html-sanitizer
  dependency-version: 7.4.13
  dependency-type: indirect
  dependency-group: composer
- dependency-name: symfony/http-foundation
  dependency-version: 7.4.13
  dependency-type: indirect
  dependency-group: composer
- dependency-name: symfony/polyfill-intl-idn
  dependency-version: 1.38.1
  dependency-type: indirect
  dependency-group: composer
- dependency-name: symfony/routing
  dependency-version: 7.4.13
  dependency-type: indirect
  dependency-group: composer
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-19 14:55:51 +00:00
24 changed files with 181 additions and 396 deletions

View File

@@ -1,16 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Enums;
use Datomatic\LaravelEnumHelper\LaravelEnumHelper;
enum TagMatchType: string
{
use LaravelEnumHelper;
case Contains = 'contains';
case NotContains = 'not_contains';
}

View File

@@ -59,7 +59,7 @@ class ReportController extends Controller
$filter->addBillable($properties->billable);
$filter->addMemberIdsFilter($properties->memberIds?->toArray());
$filter->addProjectIdsFilter($properties->projectIds?->toArray());
$filter->addTagIdsFilter($properties->tagIds?->toArray(), $properties->tagMatchType);
$filter->addTagIdsFilter($properties->tagIds?->toArray());
$filter->addTaskIdsFilter($properties->taskIds?->toArray());
$filter->addClientIdsFilter($properties->clientIds?->toArray());
$timeEntriesQuery = $filter->get();

View File

@@ -96,7 +96,6 @@ class ReportController extends Controller
$properties->setClientIds($request->input('properties.client_ids', null));
$properties->setProjectIds($request->input('properties.project_ids', null));
$properties->setTagIds($request->input('properties.tag_ids', null));
$properties->setTagMatchType($request->getPropertyTagMatchType());
$properties->setTaskIds($request->input('properties.task_ids', null));
$properties->weekStart = $request->has('properties.week_start') ? Weekday::from($request->input('properties.week_start')) : $user->week_start;
$timezone = $user->timezone;

View File

@@ -203,7 +203,7 @@ class TimeEntryController extends Controller
$filter->addMemberIdFilter($member);
$filter->addMemberIdsFilter($request->input('member_ids'));
$filter->addProjectIdsFilter($request->input('project_ids'));
$filter->addTagIdsFilter($request->input('tag_ids'), $request->getTagMatchType());
$filter->addTagIdsFilter($request->input('tag_ids'));
$filter->addTaskIdsFilter($request->input('task_ids'));
$filter->addClientIdsFilter($request->input('client_ids'));
$filter->addBillableFilter($request->input('billable'));
@@ -559,7 +559,7 @@ class TimeEntryController extends Controller
$filter->addMemberIdFilter($member);
$filter->addMemberIdsFilter($request->input('member_ids'));
$filter->addProjectIdsFilter($request->input('project_ids'));
$filter->addTagIdsFilter($request->input('tag_ids'), $request->getTagMatchType());
$filter->addTagIdsFilter($request->input('tag_ids'));
$filter->addTaskIdsFilter($request->input('task_ids'));
$filter->addClientIdsFilter($request->input('client_ids'));
$filter->addBillableFilter($request->input('billable'));

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace App\Http\Requests\V1\Report;
use App\Enums\TagMatchType;
use App\Enums\TimeEntryAggregationType;
use App\Enums\TimeEntryAggregationTypeInterval;
use App\Enums\TimeEntryRoundingType;
@@ -125,11 +124,6 @@ class ReportStoreRequest extends BaseFormRequest
}
},
],
'properties.tag_match_type' => [
'nullable',
'string',
Rule::enum(TagMatchType::class),
],
'properties.task_ids' => [
'nullable',
'array',
@@ -255,15 +249,6 @@ class ReportStoreRequest extends BaseFormRequest
return TimeEntryAggregationTypeInterval::from($this->input('properties.history_group'));
}
public function getPropertyTagMatchType(): ?TagMatchType
{
if (! $this->has('properties.tag_match_type') || $this->input('properties.tag_match_type') === null) {
return null;
}
return TagMatchType::from($this->input('properties.tag_match_type'));
}
public function getPropertyRoundingType(): ?TimeEntryRoundingType
{
if (! $this->has('properties.rounding_type') || $this->input('properties.rounding_type') === null) {

View File

@@ -5,7 +5,6 @@ declare(strict_types=1);
namespace App\Http\Requests\V1\TimeEntry;
use App\Enums\ExportFormat;
use App\Enums\TagMatchType;
use App\Enums\TimeEntryAggregationType;
use App\Enums\TimeEntryAggregationTypeInterval;
use App\Enums\TimeEntryRoundingType;
@@ -140,10 +139,6 @@ class TimeEntryAggregateExportRequest extends BaseFormRequest
})->uuid()->validate($attribute, $value, $fail);
},
],
'tag_match_type' => [
'string',
Rule::enum(TagMatchType::class),
],
// Filter by task IDs, task IDs are OR combined
'task_ids' => [
'array',
@@ -251,15 +246,6 @@ class TimeEntryAggregateExportRequest extends BaseFormRequest
return ExportFormat::from($this->validated('format'));
}
public function getTagMatchType(): ?TagMatchType
{
if (! $this->has('tag_match_type') || $this->validated('tag_match_type') === null) {
return null;
}
return TagMatchType::from($this->validated('tag_match_type'));
}
public function getRoundingType(): ?TimeEntryRoundingType
{
if (! $this->has('rounding_type') || $this->validated('rounding_type') === null) {

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace App\Http\Requests\V1\TimeEntry;
use App\Enums\TagMatchType;
use App\Enums\TimeEntryAggregationType;
use App\Enums\TimeEntryRoundingType;
use App\Http\Requests\V1\BaseFormRequest;
@@ -126,10 +125,6 @@ class TimeEntryAggregateRequest extends BaseFormRequest
})->uuid()->validate($attribute, $value, $fail);
},
],
'tag_match_type' => [
'string',
Rule::enum(TagMatchType::class),
],
// Filter by task IDs, task IDs are OR combined
'task_ids' => [
'array',
@@ -213,15 +208,6 @@ class TimeEntryAggregateRequest extends BaseFormRequest
return $this->input('end') !== null ? Carbon::createFromFormat('Y-m-d\TH:i:s\Z', $this->input('end'), 'UTC') : null;
}
public function getTagMatchType(): ?TagMatchType
{
if (! $this->has('tag_match_type') || $this->validated('tag_match_type') === null) {
return null;
}
return TagMatchType::from($this->validated('tag_match_type'));
}
public function getRoundingType(): ?TimeEntryRoundingType
{
if (! $this->has('rounding_type') || $this->validated('rounding_type') === null) {

View File

@@ -5,7 +5,6 @@ declare(strict_types=1);
namespace App\Http\Requests\V1\TimeEntry;
use App\Enums\ExportFormat;
use App\Enums\TagMatchType;
use App\Enums\TimeEntryRoundingType;
use App\Models\Client;
use App\Models\Member;
@@ -111,10 +110,6 @@ class TimeEntryIndexExportRequest extends TimeEntryIndexRequest
})->uuid()->validate($attribute, $value, $fail);
},
],
'tag_match_type' => [
'string',
Rule::enum(TagMatchType::class),
],
// Filter by task IDs, task IDs are OR combined
'task_ids' => [
'array',
@@ -220,15 +215,6 @@ class TimeEntryIndexExportRequest extends TimeEntryIndexRequest
return ExportFormat::from($this->validated('format'));
}
public function getTagMatchType(): ?TagMatchType
{
if (! $this->has('tag_match_type') || $this->validated('tag_match_type') === null) {
return null;
}
return TagMatchType::from($this->validated('tag_match_type'));
}
public function getRoundingType(): ?TimeEntryRoundingType
{
if (! $this->has('rounding_type') || $this->validated('rounding_type') === null) {

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace App\Http\Requests\V1\TimeEntry;
use App\Enums\TagMatchType;
use App\Enums\TimeEntryRoundingType;
use App\Http\Requests\V1\BaseFormRequest;
use App\Models\Client;
@@ -104,10 +103,6 @@ class TimeEntryIndexRequest extends BaseFormRequest
})->uuid()->validate($attribute, $value, $fail);
},
],
'tag_match_type' => [
'string',
Rule::enum(TagMatchType::class),
],
// Filter by task IDs, task IDs are OR combined
'task_ids' => [
'array',
@@ -195,15 +190,6 @@ class TimeEntryIndexRequest extends BaseFormRequest
return $this->has('offset') ? (int) $this->validated('offset', 0) : 0;
}
public function getTagMatchType(): ?TagMatchType
{
if (! $this->has('tag_match_type') || $this->validated('tag_match_type') === null) {
return null;
}
return TagMatchType::from($this->validated('tag_match_type'));
}
public function getRoundingType(): ?TimeEntryRoundingType
{
if (! $this->has('rounding_type') || $this->validated('rounding_type') === null) {

View File

@@ -56,8 +56,6 @@ class DetailedReportResource extends BaseResource
'project_ids' => $this->resource->properties->projectIds?->toArray(),
/** @var array<string>|null $tags_ids Filter by tag IDs, tag IDs are OR combined */
'tag_ids' => $this->resource->properties->tagIds?->toArray(),
/** @var string|null $tag_match_type Tag match type */
'tag_match_type' => $this->resource->properties->tagMatchType?->value,
/** @var array<string>|null $task_ids Filter by task IDs, task IDs are OR combined */
'task_ids' => $this->resource->properties->taskIds?->toArray(),
/** @var string|null $rounding_type Rounding type for time entries */

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace App\Service\Dto;
use App\Enums\TagMatchType;
use App\Enums\TimeEntryAggregationType;
use App\Enums\TimeEntryAggregationTypeInterval;
use App\Enums\TimeEntryRoundingType;
@@ -57,8 +56,6 @@ class ReportPropertiesDto implements Castable
*/
public ?Collection $tagIds = null;
public ?TagMatchType $tagMatchType = null;
/**
* @var Collection<int, string>|null
*/
@@ -118,7 +115,6 @@ class ReportPropertiesDto implements Castable
$dto->clientIds = $data->clientIds !== null ? ReportPropertiesDto::idArrayToCollection($data->clientIds) : null;
$dto->projectIds = $data->projectIds !== null ? ReportPropertiesDto::idArrayToCollection($data->projectIds) : null;
$dto->tagIds = $data->tagIds !== null ? ReportPropertiesDto::idArrayToCollection($data->tagIds) : null;
$dto->tagMatchType = isset($data->tagMatchType) ? TagMatchType::from($data->tagMatchType) : null;
$dto->taskIds = $data->taskIds ? ReportPropertiesDto::idArrayToCollection($data->taskIds) : null;
$dto->group = TimeEntryAggregationType::from($data->group);
$dto->subGroup = TimeEntryAggregationType::from($data->subGroup);
@@ -148,7 +144,6 @@ class ReportPropertiesDto implements Castable
'clientIds' => $value->clientIds?->toArray(),
'projectIds' => $value->projectIds?->toArray(),
'tagIds' => $value->tagIds?->toArray(),
'tagMatchType' => $value->tagMatchType?->value,
'taskIds' => $value->taskIds?->toArray(),
'group' => $value->group->value,
'subGroup' => $value->subGroup->value,
@@ -221,11 +216,6 @@ class ReportPropertiesDto implements Castable
$this->tagIds = $tagIds !== null ? ReportPropertiesDto::idArrayToCollection($tagIds) : null;
}
public function setTagMatchType(?TagMatchType $tagMatchType): void
{
$this->tagMatchType = $tagMatchType;
}
/**
* @param array<mixed>|null $taskIds
*/

View File

@@ -116,12 +116,10 @@ class ClockifyTimeEntriesImporter extends DefaultImporter
throw new ImportException('Time entry description is too long');
}
$timeEntry->description = $record['Description'];
if (isset($record['Billable'])) {
if (! in_array($record['Billable'], ['Yes', 'No'], true)) {
throw new ImportException('Invalid billable value');
}
$timeEntry->billable = $record['Billable'] === 'Yes';
if (! in_array($record['Billable'], ['Yes', 'No'], true)) {
throw new ImportException('Invalid billable value');
}
$timeEntry->billable = $record['Billable'] === 'Yes';
$timeEntry->tags = $this->getTags($record['Tags']);
$timeEntry->is_imported = true;
@@ -221,6 +219,7 @@ class ClockifyTimeEntriesImporter extends DefaultImporter
'Group',
'Email',
'Tags',
'Billable',
'Start Date',
'Start Time',
'End Date',

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace App\Service;
use App\Enums\TagMatchType;
use App\Models\Member;
use App\Models\TimeEntry;
use Illuminate\Database\Eloquent\Builder;
@@ -193,21 +192,15 @@ class TimeEntryFilter
/**
* @param array<string>|null $tagIds
*/
public function addTagIdsFilter(?array $tagIds, ?TagMatchType $tagMatchType = TagMatchType::Contains): self
public function addTagIdsFilter(?array $tagIds): self
{
if ($tagIds === null) {
return $this;
}
$tagMatchType ??= TagMatchType::Contains;
$includeNone = in_array(self::NONE_VALUE, $tagIds, true);
$tagIds = array_values(array_filter($tagIds, fn (string $id): bool => $id !== self::NONE_VALUE));
// An empty selection (no tag IDs and not filtering for "none") is no constraint, so apply nothing.
// This also prevents the not-contains branch from collapsing into "only entries with null tags".
if (count($tagIds) === 0 && ! $includeNone) {
return $this;
}
$tagCondition = function (Builder $builder) use ($tagIds, $includeNone): void {
$this->builder->where(function (Builder $builder) use ($tagIds, $includeNone): void {
foreach ($tagIds as $tagId) {
$builder->orWhereJsonContains('tags', $tagId);
}
@@ -216,18 +209,7 @@ class TimeEntryFilter
$query->whereJsonLength('tags', 0)->orWhereNull('tags');
});
}
};
if ($tagMatchType === TagMatchType::NotContains) {
$this->builder->where(function (Builder $builder) use ($tagCondition, $includeNone): void {
$builder->whereNot($tagCondition);
if (! $includeNone) {
$builder->orWhereNull('tags');
}
});
} else {
$this->builder->where($tagCondition);
}
});
return $this;
}

328
composer.lock generated
View File

@@ -3020,25 +3020,26 @@
},
{
"name": "guzzlehttp/guzzle",
"version": "7.10.3",
"version": "7.12.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "47ba23c7a55247e2e1b7407aca90e9bbed0d9d86"
"reference": "d34627490fbc03bf5c5d7cfed81f2faa19519425"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/47ba23c7a55247e2e1b7407aca90e9bbed0d9d86",
"reference": "47ba23c7a55247e2e1b7407aca90e9bbed0d9d86",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/d34627490fbc03bf5c5d7cfed81f2faa19519425",
"reference": "d34627490fbc03bf5c5d7cfed81f2faa19519425",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^2.3",
"guzzlehttp/psr7": "^2.8",
"guzzlehttp/promises": "^2.5",
"guzzlehttp/psr7": "^2.12.1",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
"symfony/deprecation-contracts": "^2.5 || ^3.0",
"symfony/polyfill-php80": "^1.24"
},
"provide": {
"psr/http-client-implementation": "1.0"
@@ -3047,7 +3048,7 @@
"bamarni/composer-bin-plugin": "^1.8.2",
"ext-curl": "*",
"guzzle/client-integration-tests": "3.0.2",
"guzzlehttp/test-server": "^0.3.2",
"guzzlehttp/test-server": "^0.5.1",
"php-http/message-factory": "^1.1",
"phpunit/phpunit": "^8.5.52 || ^9.6.34",
"psr/log": "^1.1 || ^2.0 || ^3.0"
@@ -3127,7 +3128,7 @@
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.10.3"
"source": "https://github.com/guzzle/guzzle/tree/7.12.1"
},
"funding": [
{
@@ -3143,24 +3144,25 @@
"type": "tidelift"
}
],
"time": "2026-05-20T22:59:19+00:00"
"time": "2026-06-18T14:12:49+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "2.4.1",
"version": "2.5.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2"
"reference": "4360e982f87f5f258bf872d094647791db2f4c8e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/09e8a212562fb1fb6a512c4156ed71525969d6c2",
"reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2",
"url": "https://api.github.com/repos/guzzle/promises/zipball/4360e982f87f5f258bf872d094647791db2f4c8e",
"reference": "4360e982f87f5f258bf872d094647791db2f4c8e",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0"
"php": "^7.2.5 || ^8.0",
"symfony/deprecation-contracts": "^2.5 || ^3.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
@@ -3210,7 +3212,7 @@
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/2.4.1"
"source": "https://github.com/guzzle/promises/tree/2.5.0"
},
"funding": [
{
@@ -3226,27 +3228,29 @@
"type": "tidelift"
}
],
"time": "2026-05-20T22:57:30+00:00"
"time": "2026-06-02T12:23:43+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "2.10.1",
"version": "2.12.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "73ab136360b5dfd858006eae9795e8fe43c80361"
"reference": "172ef2f4e9824c1e058b7f30be8ae25a02c0f2b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/73ab136360b5dfd858006eae9795e8fe43c80361",
"reference": "73ab136360b5dfd858006eae9795e8fe43c80361",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/172ef2f4e9824c1e058b7f30be8ae25a02c0f2b7",
"reference": "172ef2f4e9824c1e058b7f30be8ae25a02c0f2b7",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.1 || ^2.0",
"ralouphie/getallheaders": "^3.0"
"ralouphie/getallheaders": "^3.0",
"symfony/deprecation-contracts": "^2.5 || ^3.0",
"symfony/polyfill-php80": "^1.24"
},
"provide": {
"psr/http-factory-implementation": "1.0",
@@ -3327,7 +3331,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.10.1"
"source": "https://github.com/guzzle/psr7/tree/2.12.1"
},
"funding": [
{
@@ -3343,20 +3347,20 @@
"type": "tidelift"
}
],
"time": "2026-05-20T09:27:36+00:00"
"time": "2026-06-18T09:49:37+00:00"
},
{
"name": "guzzlehttp/uri-template",
"version": "v1.0.5",
"version": "v1.0.7",
"source": {
"type": "git",
"url": "https://github.com/guzzle/uri-template.git",
"reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1"
"reference": "7fe811c23a9e3cd712b4389eaeb50b5456d8c529"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1",
"reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1",
"url": "https://api.github.com/repos/guzzle/uri-template/zipball/7fe811c23a9e3cd712b4389eaeb50b5456d8c529",
"reference": "7fe811c23a9e3cd712b4389eaeb50b5456d8c529",
"shasum": ""
},
"require": {
@@ -3365,7 +3369,7 @@
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.44 || ^9.6.25",
"phpunit/phpunit": "^8.5.52 || ^9.6.34",
"uri-template/tests": "1.0.0"
},
"type": "library",
@@ -3413,7 +3417,7 @@
],
"support": {
"issues": "https://github.com/guzzle/uri-template/issues",
"source": "https://github.com/guzzle/uri-template/tree/v1.0.5"
"source": "https://github.com/guzzle/uri-template/tree/v1.0.7"
},
"funding": [
{
@@ -3429,7 +3433,7 @@
"type": "tidelift"
}
],
"time": "2025-08-22T14:27:06+00:00"
"time": "2026-06-12T21:33:43+00:00"
},
{
"name": "inertiajs/inertia-laravel",
@@ -4193,16 +4197,16 @@
},
{
"name": "laravel/framework",
"version": "v12.60.2",
"version": "v12.61.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "b8b55ce32175cc00f834a56eeb6316f18ed6ea39"
"reference": "e8472ca9774452fe50841d9bdced060679f4d58d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/b8b55ce32175cc00f834a56eeb6316f18ed6ea39",
"reference": "b8b55ce32175cc00f834a56eeb6316f18ed6ea39",
"url": "https://api.github.com/repos/laravel/framework/zipball/e8472ca9774452fe50841d9bdced060679f4d58d",
"reference": "e8472ca9774452fe50841d9bdced060679f4d58d",
"shasum": ""
},
"require": {
@@ -4411,7 +4415,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2026-05-20T11:48:19+00:00"
"time": "2026-06-04T14:22:52+00:00"
},
{
"name": "laravel/octane",
@@ -6672,16 +6676,16 @@
},
{
"name": "nesbot/carbon",
"version": "3.11.4",
"version": "3.13.0",
"source": {
"type": "git",
"url": "https://github.com/CarbonPHP/carbon.git",
"reference": "e890471a3494740f7d9326d72ce6a8c559ffee60"
"reference": "40f6618f052df16b545f626fbf9a878e6497d16a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60",
"reference": "e890471a3494740f7d9326d72ce6a8c559ffee60",
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/40f6618f052df16b545f626fbf9a878e6497d16a",
"reference": "40f6618f052df16b545f626fbf9a878e6497d16a",
"shasum": ""
},
"require": {
@@ -6773,7 +6777,7 @@
"type": "tidelift"
}
],
"time": "2026-04-07T09:57:54+00:00"
"time": "2026-06-18T13:49:15+00:00"
},
{
"name": "nette/schema",
@@ -7792,16 +7796,16 @@
},
{
"name": "phpoffice/phpspreadsheet",
"version": "1.30.4",
"version": "1.30.5",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "02970383cc12e7bf0bc0707ea6e2e8ed23a7aec9"
"reference": "97bcabd32a64924688487dcd64aceaf158affb5c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/02970383cc12e7bf0bc0707ea6e2e8ed23a7aec9",
"reference": "02970383cc12e7bf0bc0707ea6e2e8ed23a7aec9",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/97bcabd32a64924688487dcd64aceaf158affb5c",
"reference": "97bcabd32a64924688487dcd64aceaf158affb5c",
"shasum": ""
},
"require": {
@@ -7894,9 +7898,9 @@
],
"support": {
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.30.4"
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.30.5"
},
"time": "2026-04-19T06:00:39+00:00"
"time": "2026-05-31T05:13:11+00:00"
},
{
"name": "phpoption/phpoption",
@@ -7975,16 +7979,16 @@
},
{
"name": "phpseclib/phpseclib",
"version": "3.0.52",
"version": "3.0.55",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "2adaefc83df2ec548558307690f376dd7d4f4fce"
"reference": "db9744e6d47e742b1f974e965ad49bdd041105af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/2adaefc83df2ec548558307690f376dd7d4f4fce",
"reference": "2adaefc83df2ec548558307690f376dd7d4f4fce",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/db9744e6d47e742b1f974e965ad49bdd041105af",
"reference": "db9744e6d47e742b1f974e965ad49bdd041105af",
"shasum": ""
},
"require": {
@@ -8065,7 +8069,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.52"
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.55"
},
"funding": [
{
@@ -8081,7 +8085,7 @@
"type": "tidelift"
}
],
"time": "2026-04-27T07:02:15+00:00"
"time": "2026-06-14T23:24:10+00:00"
},
{
"name": "phpstan/phpdoc-parser",
@@ -9019,20 +9023,20 @@
},
{
"name": "ramsey/uuid",
"version": "4.9.2",
"version": "4.9.3",
"source": {
"type": "git",
"url": "https://github.com/ramsey/uuid.git",
"reference": "8429c78ca35a09f27565311b98101e2826affde0"
"reference": "1df15849d00943a67d677dc9cfd80795f038c9f8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0",
"reference": "8429c78ca35a09f27565311b98101e2826affde0",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/1df15849d00943a67d677dc9cfd80795f038c9f8",
"reference": "1df15849d00943a67d677dc9cfd80795f038c9f8",
"shasum": ""
},
"require": {
"brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14",
"brick/math": ">=0.8.16 <=0.18",
"php": "^8.0",
"ramsey/collection": "^1.2 || ^2.0"
},
@@ -9091,9 +9095,9 @@
],
"support": {
"issues": "https://github.com/ramsey/uuid/issues",
"source": "https://github.com/ramsey/uuid/tree/4.9.2"
"source": "https://github.com/ramsey/uuid/tree/4.9.3"
},
"time": "2025-12-14T04:43:48+00:00"
"time": "2026-06-18T03:57:49+00:00"
},
{
"name": "react/promise",
@@ -10130,16 +10134,16 @@
},
{
"name": "symfony/console",
"version": "v7.4.11",
"version": "v7.4.13",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "ed0107e43ab452aa77ae99e005b95e56b556e075"
"reference": "85095d2573eaefaf35e40b9513a9bf09f72cd217"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/ed0107e43ab452aa77ae99e005b95e56b556e075",
"reference": "ed0107e43ab452aa77ae99e005b95e56b556e075",
"url": "https://api.github.com/repos/symfony/console/zipball/85095d2573eaefaf35e40b9513a9bf09f72cd217",
"reference": "85095d2573eaefaf35e40b9513a9bf09f72cd217",
"shasum": ""
},
"require": {
@@ -10204,7 +10208,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v7.4.11"
"source": "https://github.com/symfony/console/tree/v7.4.13"
},
"funding": [
{
@@ -10224,7 +10228,7 @@
"type": "tidelift"
}
],
"time": "2026-05-13T12:04:42+00:00"
"time": "2026-05-24T08:56:14+00:00"
},
{
"name": "symfony/css-selector",
@@ -10753,16 +10757,16 @@
},
{
"name": "symfony/html-sanitizer",
"version": "v7.4.12",
"version": "v7.4.13",
"source": {
"type": "git",
"url": "https://github.com/symfony/html-sanitizer.git",
"reference": "51cb4f68195883f7ac403abb58ecf7adc74e0f9e"
"reference": "761f6c49dfd103ee08b3cd09ece588b069e18ec9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/51cb4f68195883f7ac403abb58ecf7adc74e0f9e",
"reference": "51cb4f68195883f7ac403abb58ecf7adc74e0f9e",
"url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/761f6c49dfd103ee08b3cd09ece588b069e18ec9",
"reference": "761f6c49dfd103ee08b3cd09ece588b069e18ec9",
"shasum": ""
},
"require": {
@@ -10803,7 +10807,7 @@
"sanitizer"
],
"support": {
"source": "https://github.com/symfony/html-sanitizer/tree/v7.4.12"
"source": "https://github.com/symfony/html-sanitizer/tree/v7.4.13"
},
"funding": [
{
@@ -10823,20 +10827,20 @@
"type": "tidelift"
}
],
"time": "2026-05-20T07:20:23+00:00"
"time": "2026-05-24T11:20:33+00:00"
},
{
"name": "symfony/http-foundation",
"version": "v7.4.8",
"version": "v7.4.13",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "9381209597ec66c25be154cbf2289076e64d1eab"
"reference": "bc354f47c62301e990b7874fa662326368508e2c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/9381209597ec66c25be154cbf2289076e64d1eab",
"reference": "9381209597ec66c25be154cbf2289076e64d1eab",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/bc354f47c62301e990b7874fa662326368508e2c",
"reference": "bc354f47c62301e990b7874fa662326368508e2c",
"shasum": ""
},
"require": {
@@ -10885,7 +10889,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/http-foundation/tree/v7.4.8"
"source": "https://github.com/symfony/http-foundation/tree/v7.4.13"
},
"funding": [
{
@@ -10905,20 +10909,20 @@
"type": "tidelift"
}
],
"time": "2026-03-24T13:12:05+00:00"
"time": "2026-05-24T11:20:33+00:00"
},
{
"name": "symfony/http-kernel",
"version": "v7.4.12",
"version": "v7.4.13",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "7922b53e70d2ba2027af8bb6a59d91eb3541ea4d"
"reference": "9df847980c436451f4f51d1284491bb4356dd989"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/7922b53e70d2ba2027af8bb6a59d91eb3541ea4d",
"reference": "7922b53e70d2ba2027af8bb6a59d91eb3541ea4d",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/9df847980c436451f4f51d1284491bb4356dd989",
"reference": "9df847980c436451f4f51d1284491bb4356dd989",
"shasum": ""
},
"require": {
@@ -11004,7 +11008,7 @@
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/http-kernel/tree/v7.4.12"
"source": "https://github.com/symfony/http-kernel/tree/v7.4.13"
},
"funding": [
{
@@ -11024,7 +11028,7 @@
"type": "tidelift"
}
],
"time": "2026-05-20T09:27:11+00:00"
"time": "2026-05-27T08:31:43+00:00"
},
{
"name": "symfony/mailer",
@@ -11112,16 +11116,16 @@
},
{
"name": "symfony/mime",
"version": "v7.4.12",
"version": "v7.4.13",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
"reference": "b198dd66c211c97119bcaaff7c13431dbbb5e470"
"reference": "a845722765c4f6b2ce88beaf4f4479975b186770"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/b198dd66c211c97119bcaaff7c13431dbbb5e470",
"reference": "b198dd66c211c97119bcaaff7c13431dbbb5e470",
"url": "https://api.github.com/repos/symfony/mime/zipball/a845722765c4f6b2ce88beaf4f4479975b186770",
"reference": "a845722765c4f6b2ce88beaf4f4479975b186770",
"shasum": ""
},
"require": {
@@ -11177,7 +11181,7 @@
"mime-type"
],
"support": {
"source": "https://github.com/symfony/mime/tree/v7.4.12"
"source": "https://github.com/symfony/mime/tree/v7.4.13"
},
"funding": [
{
@@ -11197,7 +11201,7 @@
"type": "tidelift"
}
],
"time": "2026-05-20T07:20:23+00:00"
"time": "2026-05-23T16:22:37+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -11284,16 +11288,16 @@
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.37.0",
"version": "v1.38.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "4864388bfbd3001ce88e234fab652acd91fdc57e"
"reference": "e9247d281d694a5120554d9afaf54e070e88a603"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e",
"reference": "4864388bfbd3001ce88e234fab652acd91fdc57e",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603",
"reference": "e9247d281d694a5120554d9afaf54e070e88a603",
"shasum": ""
},
"require": {
@@ -11342,7 +11346,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.37.0"
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1"
},
"funding": [
{
@@ -11362,20 +11366,20 @@
"type": "tidelift"
}
],
"time": "2026-04-26T13:13:48+00:00"
"time": "2026-05-26T05:58:03+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.37.0",
"version": "v1.38.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3"
"reference": "dc21118016c039a66235cf93d96b435ffb282412"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3",
"reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/dc21118016c039a66235cf93d96b435ffb282412",
"reference": "dc21118016c039a66235cf93d96b435ffb282412",
"shasum": ""
},
"require": {
@@ -11429,7 +11433,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.37.0"
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.38.1"
},
"funding": [
{
@@ -11449,20 +11453,20 @@
"type": "tidelift"
}
],
"time": "2024-09-10T14:38:51+00:00"
"time": "2026-05-25T15:22:23+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.37.0",
"version": "v1.38.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "3833d7255cc303546435cb650316bff708a1c75c"
"reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c",
"reference": "3833d7255cc303546435cb650316bff708a1c75c",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b",
"reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b",
"shasum": ""
},
"require": {
@@ -11514,7 +11518,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.37.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0"
},
"funding": [
{
@@ -11534,20 +11538,20 @@
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
"time": "2026-05-25T13:48:31+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.37.0",
"version": "v1.38.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315"
"reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315",
"reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6",
"reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6",
"shasum": ""
},
"require": {
@@ -11599,7 +11603,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2"
},
"funding": [
{
@@ -11619,7 +11623,7 @@
"type": "tidelift"
}
],
"time": "2026-04-10T17:25:58+00:00"
"time": "2026-05-27T06:59:30+00:00"
},
{
"name": "symfony/polyfill-php73",
@@ -11787,16 +11791,16 @@
},
{
"name": "symfony/polyfill-php81",
"version": "v1.37.0",
"version": "v1.38.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
"reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/6bfb9c766cacffbc8e118cb87217d08ed84e5cd7",
"reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7",
"shasum": ""
},
"require": {
@@ -11843,7 +11847,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.37.0"
"source": "https://github.com/symfony/polyfill-php81/tree/v1.38.1"
},
"funding": [
{
@@ -11863,20 +11867,20 @@
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
"time": "2026-05-26T12:45:58+00:00"
},
{
"name": "symfony/polyfill-php83",
"version": "v1.37.0",
"version": "v1.38.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php83.git",
"reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149"
"reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/3600c2cb22399e25bb226e4a135ce91eeb2a6149",
"reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149",
"url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/796a26abb75ce49f3a84433cd81bf1009d73d5f8",
"reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8",
"shasum": ""
},
"require": {
@@ -11923,7 +11927,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php83/tree/v1.37.0"
"source": "https://github.com/symfony/polyfill-php83/tree/v1.38.2"
},
"funding": [
{
@@ -11943,20 +11947,20 @@
"type": "tidelift"
}
],
"time": "2026-04-10T17:25:58+00:00"
"time": "2026-05-27T06:51:48+00:00"
},
{
"name": "symfony/polyfill-php84",
"version": "v1.37.0",
"version": "v1.38.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php84.git",
"reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06"
"reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06",
"reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06",
"url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa",
"reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa",
"shasum": ""
},
"require": {
@@ -12003,7 +12007,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0"
"source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1"
},
"funding": [
{
@@ -12023,20 +12027,20 @@
"type": "tidelift"
}
],
"time": "2026-04-10T18:47:49+00:00"
"time": "2026-05-26T12:51:13+00:00"
},
{
"name": "symfony/polyfill-php85",
"version": "v1.37.0",
"version": "v1.38.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php85.git",
"reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee"
"reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee",
"reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee",
"url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1",
"reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1",
"shasum": ""
},
"require": {
@@ -12083,7 +12087,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php85/tree/v1.37.0"
"source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1"
},
"funding": [
{
@@ -12103,7 +12107,7 @@
"type": "tidelift"
}
],
"time": "2026-04-26T13:10:57+00:00"
"time": "2026-05-26T02:25:22+00:00"
},
{
"name": "symfony/polyfill-uuid",
@@ -12190,16 +12194,16 @@
},
{
"name": "symfony/process",
"version": "v7.4.11",
"version": "v7.4.13",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "d9593c9efa40499eb078b81144de42cbc28a31f0"
"reference": "f5804be144caceb570f6747519999636b664f24c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/d9593c9efa40499eb078b81144de42cbc28a31f0",
"reference": "d9593c9efa40499eb078b81144de42cbc28a31f0",
"url": "https://api.github.com/repos/symfony/process/zipball/f5804be144caceb570f6747519999636b664f24c",
"reference": "f5804be144caceb570f6747519999636b664f24c",
"shasum": ""
},
"require": {
@@ -12231,7 +12235,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v7.4.11"
"source": "https://github.com/symfony/process/tree/v7.4.13"
},
"funding": [
{
@@ -12251,7 +12255,7 @@
"type": "tidelift"
}
],
"time": "2026-05-11T16:55:21+00:00"
"time": "2026-05-23T16:05:06+00:00"
},
{
"name": "symfony/property-access",
@@ -12514,16 +12518,16 @@
},
{
"name": "symfony/routing",
"version": "v7.4.12",
"version": "v7.4.13",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
"reference": "3b04a5ec4887a8135a12ebf0f4cbc5b8fc8ee204"
"reference": "3a162171bb008e5e0f15dce6581373a4c0e8390d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/3b04a5ec4887a8135a12ebf0f4cbc5b8fc8ee204",
"reference": "3b04a5ec4887a8135a12ebf0f4cbc5b8fc8ee204",
"url": "https://api.github.com/repos/symfony/routing/zipball/3a162171bb008e5e0f15dce6581373a4c0e8390d",
"reference": "3a162171bb008e5e0f15dce6581373a4c0e8390d",
"shasum": ""
},
"require": {
@@ -12575,7 +12579,7 @@
"url"
],
"support": {
"source": "https://github.com/symfony/routing/tree/v7.4.12"
"source": "https://github.com/symfony/routing/tree/v7.4.13"
},
"funding": [
{
@@ -12595,7 +12599,7 @@
"type": "tidelift"
}
],
"time": "2026-05-20T07:20:23+00:00"
"time": "2026-05-24T11:20:33+00:00"
},
{
"name": "symfony/serializer",
@@ -12790,16 +12794,16 @@
},
{
"name": "symfony/string",
"version": "v7.4.11",
"version": "v7.4.13",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "965f7306a43383d02c6aca1e3f3bd2f0ea5dee15"
"reference": "961683010db3b27ec6ebcd7308e6e1ee8fa7ffde"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/965f7306a43383d02c6aca1e3f3bd2f0ea5dee15",
"reference": "965f7306a43383d02c6aca1e3f3bd2f0ea5dee15",
"url": "https://api.github.com/repos/symfony/string/zipball/961683010db3b27ec6ebcd7308e6e1ee8fa7ffde",
"reference": "961683010db3b27ec6ebcd7308e6e1ee8fa7ffde",
"shasum": ""
},
"require": {
@@ -12857,7 +12861,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v7.4.11"
"source": "https://github.com/symfony/string/tree/v7.4.13"
},
"funding": [
{
@@ -12877,7 +12881,7 @@
"type": "tidelift"
}
],
"time": "2026-05-13T12:04:42+00:00"
"time": "2026-05-23T15:23:29+00:00"
},
{
"name": "symfony/translation",
@@ -13823,16 +13827,16 @@
},
{
"name": "webmozart/assert",
"version": "2.4.0",
"version": "2.4.1",
"source": {
"type": "git",
"url": "https://github.com/webmozarts/assert.git",
"reference": "9007ea6f45ecf352a9422b36644e4bfc039b9155"
"reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozarts/assert/zipball/9007ea6f45ecf352a9422b36644e4bfc039b9155",
"reference": "9007ea6f45ecf352a9422b36644e4bfc039b9155",
"url": "https://api.github.com/repos/webmozarts/assert/zipball/2ccb7c2e821038c03a3e6e1700c570c158c55f70",
"reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70",
"shasum": ""
},
"require": {
@@ -13883,9 +13887,9 @@
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
"source": "https://github.com/webmozarts/assert/tree/2.4.0"
"source": "https://github.com/webmozarts/assert/tree/2.4.1"
},
"time": "2026-05-20T13:07:01+00:00"
"time": "2026-06-15T15:31:57+00:00"
},
{
"name": "wikimedia/composer-merge-plugin",

View File

@@ -14,7 +14,6 @@ import DateRangePicker from '@/packages/ui/src/Input/DateRangePicker.vue';
import TagDropdown from '@/packages/ui/src/Tag/TagDropdown.vue';
import { useTagsQuery } from '@/utils/useTagsQuery';
import { useTagsStore } from '@/utils/useTags';
import type { TagMatchType } from '@/types/reporting';
type TimeEntryRoundingType = 'up' | 'down' | 'nearest';
@@ -23,7 +22,6 @@ const selectedProjects = defineModel<string[]>('selectedProjects', { required: t
const selectedTasks = defineModel<string[]>('selectedTasks', { required: true });
const selectedClients = defineModel<string[]>('selectedClients', { required: true });
const selectedTags = defineModel<string[]>('selectedTags', { required: true });
const tagMatchType = defineModel<TagMatchType>('tagMatchType', { required: true });
const billable = defineModel<'true' | 'false' | null>('billable', { required: true });
const roundingEnabled = defineModel<boolean>('roundingEnabled', { required: true });
const roundingType = defineModel<TimeEntryRoundingType>('roundingType', { required: true });
@@ -95,44 +93,6 @@ async function createTag(name: string) {
title="Tags"
:icon="TagIcon" />
</template>
<template #content-before-list>
<div class="mt-2 border-b border-card-background-separator pb-2">
<div
class="mb-1.5 px-2 text-xs font-medium text-text-tertiary uppercase">
Match
</div>
<div class="space-y-1">
<button
type="button"
class="w-full rounded-md px-2 py-1.5 text-left text-sm font-medium"
:class="
tagMatchType === 'contains'
? 'bg-card-background-active text-text-primary'
: 'text-text-secondary hover:bg-card-background-active'
"
@click="
tagMatchType = 'contains';
emit('submit');
">
Contains
</button>
<button
type="button"
class="w-full rounded-md px-2 py-1.5 text-left text-sm font-medium"
:class="
tagMatchType === 'not_contains'
? 'bg-card-background-active text-text-primary'
: 'text-text-secondary hover:bg-card-background-active'
"
@click="
tagMatchType = 'not_contains';
emit('submit');
">
Does Not Contain
</button>
</div>
</div>
</template>
</TagDropdown>
<Select v-model="billable" @update:model-value="emit('submit')">

View File

@@ -49,7 +49,6 @@ import type { ExportFormat } from '@/types/reporting';
import { getRandomColorWithSeed } from '@/packages/ui/src/utils/color';
import { useProjectsQuery } from '@/utils/useProjectsQuery';
import { useAggregatedTimeEntriesQuery } from '@/utils/useAggregatedTimeEntriesQuery';
import type { TagMatchType } from '@/types/reporting';
type TimeEntryRoundingType = 'up' | 'down' | 'nearest';
@@ -68,7 +67,6 @@ const selectedProjects = ref<string[]>([]);
const selectedMembers = ref<string[]>([]);
const selectedTasks = ref<string[]>([]);
const selectedClients = ref<string[]>([]);
const tagMatchType = ref<TagMatchType>('contains');
const billable = ref<'true' | 'false' | null>(null);
const roundingEnabled = ref<boolean>(false);
@@ -124,7 +122,6 @@ const filterParams = computed<AggregatedTimeEntriesQueryParams>(() => {
task_ids: selectedTasks.value.length > 0 ? selectedTasks.value : undefined,
client_ids: selectedClients.value.length > 0 ? selectedClients.value : undefined,
tag_ids: selectedTags.value.length > 0 ? selectedTags.value : undefined,
tag_match_type: selectedTags.value.length > 0 ? tagMatchType.value : undefined,
billable: billable.value !== null ? billable.value : undefined,
member_id: getCurrentRole() === 'employee' ? getCurrentMembershipId() : undefined,
rounding_type: roundingEnabled.value ? roundingType.value : undefined,
@@ -369,7 +366,6 @@ const tableData = computed(() => {
v-model:selected-tasks="selectedTasks"
v-model:selected-clients="selectedClients"
v-model:selected-tags="selectedTags"
v-model:tag-match-type="tagMatchType"
v-model:billable="billable"
v-model:rounding-enabled="roundingEnabled"
v-model:rounding-type="roundingType"

View File

@@ -67,7 +67,6 @@ import ReportingFilterBar from '@/Components/Common/Reporting/ReportingFilterBar
import { useTimeEntriesReportQuery } from '@/utils/useTimeEntriesReportQuery';
import { useTimeEntriesMutations } from '@/utils/useTimeEntriesMutations';
import { useOrganizationQuery } from '@/utils/useOrganizationQuery';
import type { TagMatchType } from '@/types/reporting';
// TimeEntryRoundingType is now defined in ReportingRoundingControls component
type TimeEntryRoundingType = 'up' | 'down' | 'nearest';
@@ -85,7 +84,6 @@ const selectedProjects = ref<string[]>([]);
const selectedMembers = ref<string[]>([]);
const selectedTasks = ref<string[]>([]);
const selectedClients = ref<string[]>([]);
const tagMatchType = ref<TagMatchType>('contains');
const billable = ref<'true' | 'false' | null>(null);
const roundingEnabled = ref<boolean>(false);
const roundingType = ref<TimeEntryRoundingType>('nearest');
@@ -117,7 +115,6 @@ function getFilterAttributes() {
task_ids: selectedTasks.value.length > 0 ? selectedTasks.value : undefined,
client_ids: selectedClients.value.length > 0 ? selectedClients.value : undefined,
tag_ids: selectedTags.value.length > 0 ? selectedTags.value : undefined,
tag_match_type: selectedTags.value.length > 0 ? tagMatchType.value : undefined,
billable: billable.value !== null ? billable.value : undefined,
rounding_type: roundingEnabled.value ? roundingType.value : undefined,
rounding_minutes: roundingEnabled.value ? roundingMinutes.value : undefined,
@@ -340,7 +337,6 @@ async function downloadExport(format: ExportFormat) {
v-model:selected-tasks="selectedTasks"
v-model:selected-clients="selectedClients"
v-model:selected-tags="selectedTags"
v-model:tag-match-type="tagMatchType"
v-model:billable="billable"
v-model:rounding-enabled="roundingEnabled"
v-model:rounding-type="roundingType"

View File

@@ -448,7 +448,6 @@ const ReportStoreRequest = z
client_ids: z.union([z.array(z.string()), z.null()]).optional(),
project_ids: z.union([z.array(z.string()), z.null()]).optional(),
tag_ids: z.union([z.array(z.string()), z.null()]).optional(),
tag_match_type: z.enum(['contains', 'not_contains']).optional(),
task_ids: z.union([z.array(z.string()), z.null()]).optional(),
group: TimeEntryAggregationType,
sub_group: TimeEntryAggregationType,
@@ -482,7 +481,6 @@ const DetailedReportResource = z
client_ids: z.union([z.array(z.string()), z.null()]),
project_ids: z.union([z.array(z.string()), z.null()]),
tag_ids: z.union([z.array(z.string()), z.null()]),
tag_match_type: z.union([z.enum(['contains', 'not_contains']), z.null()]),
task_ids: z.union([z.array(z.string()), z.null()]),
rounding_type: z.union([z.string(), z.null()]),
rounding_minutes: z.union([z.number(), z.null()]),
@@ -3786,11 +3784,6 @@ Users with the permission &#x60;time-entries:view:own&#x60; can only use this en
type: 'Query',
schema: z.array(z.string()).min(1).optional(),
},
{
name: 'tag_match_type',
type: 'Query',
schema: z.enum(['contains', 'not_contains']).optional(),
},
{
name: 'task_ids',
type: 'Query',
@@ -4172,11 +4165,6 @@ If the group parameters are all set to &#x60;null&#x60; or are all missing, the
type: 'Query',
schema: z.array(z.string()).min(1).optional(),
},
{
name: 'tag_match_type',
type: 'Query',
schema: z.enum(['contains', 'not_contains']).optional(),
},
{
name: 'task_ids',
type: 'Query',
@@ -4371,11 +4359,6 @@ If the group parameters are all set to &#x60;null&#x60; or are all missing, the
type: 'Query',
schema: z.array(z.string()).min(1).optional(),
},
{
name: 'tag_match_type',
type: 'Query',
schema: z.enum(['contains', 'not_contains']).optional(),
},
{
name: 'task_ids',
type: 'Query',
@@ -4504,11 +4487,6 @@ If the group parameters are all set to &#x60;null&#x60; or are all missing, the
type: 'Query',
schema: z.array(z.string()).min(1).optional(),
},
{
name: 'tag_match_type',
type: 'Query',
schema: z.enum(['contains', 'not_contains']).optional(),
},
{
name: 'task_ids',
type: 'Query',

View File

@@ -114,7 +114,6 @@ const showCreateTagModal = ref(false);
class="w-full rounded-md border border-input-border bg-input-background px-3 py-1.5 text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none"
placeholder="Search for a Tag..." />
</ComboboxAnchor>
<slot name="content-before-list"></slot>
<ComboboxContent
:dismiss-able="false"
position="inline"

View File

@@ -1,2 +1 @@
export type ExportFormat = 'xlsx' | 'csv' | 'ods' | 'pdf';
export type TagMatchType = 'contains' | 'not_contains';

View File

@@ -1,3 +0,0 @@
"Project","Client","Description","Task","User","Group","Email","Tags","Start Date","Start Time","End Date","End Time","Duration (h)","Duration (decimal)","Billable Rate (USD)","Billable Amount (USD)"
"Project without Client","","","","Peter Tester","","peter.test@email.test","Development, Backend","03/04/2024","10:23:52 AM","03/04/2024","10:23:52 AM","00:00:00","0.00","0.00","0.00"
"Project for Big Company","Big Company","Working hard","Task 1","Peter Tester","","peter.test@email.test","","03/04/2024","10:23 AM","03/04/2024","11:23:01 AM","01:00:01","0.00","0.00","0.00"
1 Project Client Description Task User Group Email Tags Start Date Start Time End Date End Time Duration (h) Duration (decimal) Billable Rate (USD) Billable Amount (USD)
2 Project without Client Peter Tester peter.test@email.test Development, Backend 03/04/2024 10:23:52 AM 03/04/2024 10:23:52 AM 00:00:00 0.00 0.00 0.00
3 Project for Big Company Big Company Working hard Task 1 Peter Tester peter.test@email.test 03/04/2024 10:23 AM 03/04/2024 11:23:01 AM 01:00:01 0.00 0.00 0.00

View File

@@ -41,30 +41,6 @@ class ClockifyTimeEntriesImporterTest extends ImporterTestAbstract
$this->assertSame(1, $report->clientsCreated);
}
public function test_import_of_test_file_without_billable_works_and_defaults_to_non_billable(): void
{
// Arrange
$organization = Organization::factory()->create();
$timezone = 'Europe/Vienna';
$importer = new ClockifyTimeEntriesImporter;
$importer->init($organization);
$data = Storage::disk('testfiles')->get('clockify_time_entries_import_test_4.csv');
// Act
$importer->importData($data, $timezone);
$report = $importer->getReport();
// Assert
$testScenario = $this->checkTestScenarioAfterImportExcludingTimeEntries(false, true);
$this->checkTimeEntries($testScenario, false, true);
$this->assertSame(2, $report->timeEntriesCreated);
$this->assertSame(2, $report->tagsCreated);
$this->assertSame(1, $report->tasksCreated);
$this->assertSame(1, $report->usersCreated);
$this->assertSame(2, $report->projectsCreated);
$this->assertSame(1, $report->clientsCreated);
}
public function test_import_of_test_with_special_characters_description_succeeds(): void
{
// Arrange

View File

@@ -26,7 +26,7 @@ class ImporterTestAbstract extends TestCase
/**
* @return object{user1: User, project1: Project, project2: Project, tag1: Tag, tag2: Tag}
*/
protected function checkTestScenarioAfterImportExcludingTimeEntries(bool $detailed = false, bool $billableDefault = false): object
protected function checkTestScenarioAfterImportExcludingTimeEntries(bool $detailed = false): object
{
$users = User::all();
$this->assertCount(2, $users);
@@ -80,12 +80,12 @@ class ImporterTestAbstract extends TestCase
$this->assertSame('#ef5350', $project1->color);
$this->assertSame(null, $project1->billable_rate);
// Project for Big Company
$this->assertSame(! $billableDefault, $project2->is_billable);
$this->assertSame(true, $project2->is_billable);
$this->assertSame(false, $project2->is_public);
$this->assertSame('#ec407a', $project2->color);
$this->assertSame(10001, $project2->billable_rate);
// Project (Archived)
$this->assertSame(! $billableDefault, $project3->is_billable);
$this->assertSame(true, $project3->is_billable);
$this->assertSame(true, $project3->is_public);
$this->assertSame('#6a407f', $project3->color);
$this->assertSame(null, $project3->billable_rate);
@@ -176,7 +176,7 @@ class ImporterTestAbstract extends TestCase
/**
* @param object{user1: User, project1: Project, project2: Project, tag1: Tag, tag2: Tag} $testScenario
*/
protected function checkTimeEntries(object $testScenario, bool $secondRun = false, bool $billableDefault = false): void
protected function checkTimeEntries(object $testScenario, bool $secondRun = false): void
{
$timeEntries = TimeEntry::all();
if ($secondRun) {
@@ -197,7 +197,7 @@ class ImporterTestAbstract extends TestCase
$this->assertSame('Working hard', $timeEntry2->description);
$this->assertSame('2024-03-04 09:23:00', $timeEntry2->start->toDateTimeString());
$this->assertSame('2024-03-04 10:23:01', $timeEntry2->end->toDateTimeString());
$this->assertSame(! $billableDefault, $timeEntry2->billable);
$this->assertTrue($timeEntry2->billable);
$this->assertTrue($timeEntry2->is_imported);
$this->assertSame([], $timeEntry2->tags);
}

View File

@@ -14,7 +14,6 @@ async function getConfig() {
const additionalPlugins = await collectModulePlugins('extensions');
return defineConfig({
base: './',
build: {
sourcemap: true, // Source map generation must be turned on
},