Merge remote-tracking branch 'upstream/laravel-11' into laravel-11-remove-doctrine-dbal

This commit is contained in:
Hafez Divandari
2024-02-21 16:38:53 +03:30
326 changed files with 8060 additions and 1485 deletions
-3
View File
@@ -1,4 +1 @@
@danharrin
*.blade.php @zepfietje
*.css @zepfietje
+33
View File
@@ -0,0 +1,33 @@
body:
- type: dropdown
id: package
attributes:
label: Package
description: Select the specific package you need assistance with
options:
- Panel builder
- Table builder
- Form builder
- Infolist builder
- Actions
- Notifications
- Widgets
- Other
default: 0
validations:
required: true
- type: input
id: package-version
attributes:
label: Package Version
description: Provide the full version number of the package you have installed (e.g., v3.0.0).
placeholder: v3.0.0
validations:
required: true
- type: textarea
id: description
attributes:
label: How can we help you?
description: Please provide detailed information about the issue you're experiencing. Include details such as what is happening, what you are trying to achieve, steps you've taken, and any error messages encountered. Add code examples. Include them inside triple backticks so GitHub can format them. Trim needless indentation so people on mobile can read your code. **Don’t send screenshots of code**.
validations:
required: true
+1 -1
View File
@@ -89,7 +89,7 @@ body:
id: reproduction
attributes:
label: Reproduction repository
description: The URL of a public GitHub repository which reproduces the problem. **Please do not link to your actual project**, what we need instead is a _minimal_ reproduction in a fresh project without any unnecessary code. This means it doesn\'t matter if your real project is private / confidential, since we want a link to a separate, isolated reproduction. This allows us to fix the problem much quicker. **This issue will be automatically closed and not reviewed if this is missing. Please make sure to format the URL starting with `https://github.com` - only repositories hosted on GitHub are accepted.** [Need a headstart? We have a template Filament project for you.](https://filament-issue.unitedbycode.com/)
description: The URL of a public GitHub repository which reproduces the problem. **Please do not link to your actual project**, what we need instead is a _minimal_ reproduction in a fresh project without any unnecessary code. This means it doesn\'t matter if your real project is private / confidential, since we want a link to a separate, isolated reproduction. This allows us to fix the problem much quicker. **This issue will be automatically closed and not reviewed if this is missing. Please make sure to format the URL starting with `https://github.com` - only repositories hosted on GitHub are accepted.** [Need a headstart? We have a template Filament project for you.](https://filament-issue.unitedbycode.com)
validations:
required: true
- type: textarea
+2 -2
View File
@@ -1,6 +1,6 @@
{
"plugins": ["prettier-plugin-blade", "prettier-plugin-tailwindcss"],
"semi": false,
"singleQuote": true,
"tailwindConfig": "./packages/panels/tailwind.config.js",
"trailingComma": "all"
"tailwindConfig": "./packages/panels/tailwind.config.js"
}
+4 -7
View File
@@ -55,8 +55,8 @@ further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting Ryan Scherler at ryan@eastslope.studio. All
complaints will be reviewed and investigated and will result in a response that
reported by contacting Dan Harrin at [dan@danharrin.com](mailto:dan@danharrin.com).
All complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
@@ -67,10 +67,7 @@ members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html), version 1.4.
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
[the FAQs](https://www.contributor-covenant.org/faq).
+1 -45
View File
@@ -75,51 +75,7 @@ composer require filament/widgets
## Contributing
If you want to contribute to the Filament packages, then you may want to test it in a real Laravel project:
- Fork this repository to your GitHub account.
- Create a Laravel app locally.
- Clone your fork in your Laravel app's root directory.
- In the `/filament` directory, create a branch for your fix, e.g. `fix/error-message`.
Install the packages in your app's `composer.json`:
```jsonc
{
// ...
"require": {
"filament/filament": "*",
},
"minimum-stability": "dev",
"repositories": [
{
"type": "path",
"url": "filament/packages/*"
}
],
// ...
}
```
Now, run `composer update`.
### Checking for missing translations
Set up a Laravel app, and install the [admin panel](https://filamentphp.com/docs/admin/installation).
Now, if you want to check for missing Spanish translations, run:
```bash
php artisan filament:check-translations es
```
This will let you know which translations are missing for this locale. You can make a PR with the changes to this repository.
If you've published the translations into your app and you'd like to check those instead, try:
```bash
php artisan filament:check-translations es --source=app
```
Please see our [contributing guide](https://filamentphp.com/docs/support/contributing).
## Need Help?
+2 -1
View File
@@ -26,7 +26,6 @@ $app = (new Application($basePathLocator::applicationBasePath()))
->createApplication();
$app->register(LivewireServiceProvider::class);
$app->register(AdminPanelProvider::class);
$app->register(FilamentServiceProvider::class);
$app->register(ActionsServiceProvider::class);
$app->register(FormsServiceProvider::class);
@@ -37,4 +36,6 @@ $app->register(SupportServiceProvider::class);
$app->register(TablesServiceProvider::class);
$app->register(WidgetsServiceProvider::class);
$app->register(AdminPanelProvider::class);
return $app;
+1 -1
View File
@@ -15,7 +15,7 @@
"larastan/larastan": "^2.2",
"laravel/cashier": "^14.2",
"laravel/pint": "^1.0",
"league/csv": "9.11.0",
"league/csv": "^9.14",
"league/flysystem-aws-s3-v3": "^3.0",
"nunomaduro/termwind": "^1.0|^2.0",
"openspout/openspout": "^4.23",
@@ -292,6 +292,26 @@ class TablesDemo extends Component implements HasForms, HasTable
]);
}
public function columnVerticalAlignment(Table $table): Table
{
return $this->usersTable($table)
->columns([
TextColumn::make('name')
->verticallyAlignStart(),
TextColumn::make('email')
->label('Email addresses')
->getStateUsing(fn ($record): array => [
$record->email,
str($record->email)->replace('filamentphp.com', 'filament.dev'),
])
->listWithLineBreaks(),
IconColumn::make('email_verified_at')
->label('Verified')
->boolean()
->getStateUsing(fn ($record) => filled($record->email_verified_at)),
]);
}
public function columnGrouping(Table $table): Table
{
return $this->postsTable($table)
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

+9
View File
@@ -2049,6 +2049,15 @@ export default {
deviceScaleFactor: 3,
},
},
'tables/columns/vertical-alignment': {
url: 'tables?table=columnVerticalAlignment',
selector: 'body',
viewport: {
width: 1080,
height: 640,
deviceScaleFactor: 3,
},
},
'tables/columns/grouping': {
url: 'tables?table=columnGrouping',
selector: 'body',
+236 -226
View File
@@ -171,9 +171,9 @@
}
},
"node_modules/@babel/core": {
"version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz",
"integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz",
"integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
@@ -181,11 +181,11 @@
"@babel/generator": "^7.23.6",
"@babel/helper-compilation-targets": "^7.23.6",
"@babel/helper-module-transforms": "^7.23.3",
"@babel/helpers": "^7.23.7",
"@babel/parser": "^7.23.6",
"@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.7",
"@babel/types": "^7.23.6",
"@babel/helpers": "^7.23.9",
"@babel/parser": "^7.23.9",
"@babel/template": "^7.23.9",
"@babel/traverse": "^7.23.9",
"@babel/types": "^7.23.9",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -274,9 +274,9 @@
}
},
"node_modules/@babel/helper-create-class-features-plugin": {
"version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.7.tgz",
"integrity": "sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==",
"version": "7.23.10",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz",
"integrity": "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==",
"dev": true,
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.22.5",
@@ -557,14 +557,14 @@
}
},
"node_modules/@babel/helpers": {
"version": "7.23.8",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz",
"integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz",
"integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==",
"dev": true,
"dependencies": {
"@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.7",
"@babel/types": "^7.23.6"
"@babel/template": "^7.23.9",
"@babel/traverse": "^7.23.9",
"@babel/types": "^7.23.9"
},
"engines": {
"node": ">=6.9.0"
@@ -647,9 +647,9 @@
}
},
"node_modules/@babel/parser": {
"version": "7.23.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
"integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
"integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@@ -989,9 +989,9 @@
}
},
"node_modules/@babel/plugin-transform-async-generator-functions": {
"version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.7.tgz",
"integrity": "sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz",
"integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==",
"dev": true,
"dependencies": {
"@babel/helper-environment-visitor": "^7.22.20",
@@ -1347,9 +1347,9 @@
}
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
"version": "7.23.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz",
"integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz",
"integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==",
"dev": true,
"dependencies": {
"@babel/helper-hoist-variables": "^7.22.5",
@@ -1607,16 +1607,16 @@
}
},
"node_modules/@babel/plugin-transform-runtime": {
"version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.7.tgz",
"integrity": "sha512-fa0hnfmiXc9fq/weK34MUV0drz2pOL/vfKWvN7Qw127hiUPabFCUMgAbYWcchRzMJit4o5ARsK/s+5h0249pLw==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.9.tgz",
"integrity": "sha512-A7clW3a0aSjm3ONU9o2HAILSegJCYlEZmOhmBRReVtIpY/Z/p7yIZ+wR41Z+UipwdGuqwtID/V/dOdZXjwi9gQ==",
"dev": true,
"dependencies": {
"@babel/helper-module-imports": "^7.22.15",
"@babel/helper-plugin-utils": "^7.22.5",
"babel-plugin-polyfill-corejs2": "^0.4.7",
"babel-plugin-polyfill-corejs3": "^0.8.7",
"babel-plugin-polyfill-regenerator": "^0.5.4",
"babel-plugin-polyfill-corejs2": "^0.4.8",
"babel-plugin-polyfill-corejs3": "^0.9.0",
"babel-plugin-polyfill-regenerator": "^0.5.5",
"semver": "^6.3.1"
},
"engines": {
@@ -1775,9 +1775,9 @@
}
},
"node_modules/@babel/preset-env": {
"version": "7.23.8",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.8.tgz",
"integrity": "sha512-lFlpmkApLkEP6woIKprO6DO60RImpatTQKtz4sUcDjVcK8M8mQ4sZsuxaTMNOZf0sqAq/ReYW1ZBHnOQwKpLWA==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz",
"integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==",
"dev": true,
"dependencies": {
"@babel/compat-data": "^7.23.5",
@@ -1807,7 +1807,7 @@
"@babel/plugin-syntax-top-level-await": "^7.14.5",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
"@babel/plugin-transform-arrow-functions": "^7.23.3",
"@babel/plugin-transform-async-generator-functions": "^7.23.7",
"@babel/plugin-transform-async-generator-functions": "^7.23.9",
"@babel/plugin-transform-async-to-generator": "^7.23.3",
"@babel/plugin-transform-block-scoped-functions": "^7.23.3",
"@babel/plugin-transform-block-scoping": "^7.23.4",
@@ -1829,7 +1829,7 @@
"@babel/plugin-transform-member-expression-literals": "^7.23.3",
"@babel/plugin-transform-modules-amd": "^7.23.3",
"@babel/plugin-transform-modules-commonjs": "^7.23.3",
"@babel/plugin-transform-modules-systemjs": "^7.23.3",
"@babel/plugin-transform-modules-systemjs": "^7.23.9",
"@babel/plugin-transform-modules-umd": "^7.23.3",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
"@babel/plugin-transform-new-target": "^7.23.3",
@@ -1855,9 +1855,9 @@
"@babel/plugin-transform-unicode-regex": "^7.23.3",
"@babel/plugin-transform-unicode-sets-regex": "^7.23.3",
"@babel/preset-modules": "0.1.6-no-external-plugins",
"babel-plugin-polyfill-corejs2": "^0.4.7",
"babel-plugin-polyfill-corejs3": "^0.8.7",
"babel-plugin-polyfill-regenerator": "^0.5.4",
"babel-plugin-polyfill-corejs2": "^0.4.8",
"babel-plugin-polyfill-corejs3": "^0.9.0",
"babel-plugin-polyfill-regenerator": "^0.5.5",
"core-js-compat": "^3.31.0",
"semver": "^6.3.1"
},
@@ -1898,9 +1898,9 @@
"dev": true
},
"node_modules/@babel/runtime": {
"version": "7.23.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz",
"integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
"integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
"dev": true,
"dependencies": {
"regenerator-runtime": "^0.14.0"
@@ -1910,23 +1910,23 @@
}
},
"node_modules/@babel/template": {
"version": "7.22.15",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz",
"integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.22.13",
"@babel/parser": "^7.22.15",
"@babel/types": "^7.22.15"
"@babel/code-frame": "^7.23.5",
"@babel/parser": "^7.23.9",
"@babel/types": "^7.23.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
"version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
"integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz",
"integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.23.5",
@@ -1935,8 +1935,8 @@
"@babel/helper-function-name": "^7.23.0",
"@babel/helper-hoist-variables": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
"@babel/parser": "^7.23.6",
"@babel/types": "^7.23.6",
"@babel/parser": "^7.23.9",
"@babel/types": "^7.23.9",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -1945,9 +1945,9 @@
}
},
"node_modules/@babel/types": {
"version": "7.23.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
"integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz",
"integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==",
"dev": true,
"dependencies": {
"@babel/helper-string-parser": "^7.23.4",
@@ -2480,9 +2480,9 @@
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.21",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz",
"integrity": "sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g==",
"version": "0.3.22",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
"integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -2743,9 +2743,9 @@
}
},
"node_modules/@types/express/node_modules/@types/express-serve-static-core": {
"version": "4.17.41",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz",
"integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==",
"version": "4.17.43",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz",
"integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==",
"dev": true,
"dependencies": {
"@types/node": "*",
@@ -2850,9 +2850,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "20.11.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz",
"integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==",
"version": "20.11.16",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz",
"integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
@@ -3274,9 +3274,9 @@
"dev": true
},
"node_modules/alpinejs": {
"version": "3.13.3",
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.3.tgz",
"integrity": "sha512-WZ6WQjkAOl+WdW/jukzNHq9zHFDNKmkk/x6WF7WdyNDD6woinrfXCVsZXm0galjbco+pEpYmJLtwlZwcOfIVdg==",
"version": "3.13.5",
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.5.tgz",
"integrity": "sha512-1d2XeNGN+Zn7j4mUAKXtAgdc4/rLeadyTMWeJGXF5DzwawPBxwTiBhFFm6w/Ei8eJxUZeyNWWSD9zknfdz1kEw==",
"dev": true,
"dependencies": {
"@vue/reactivity": "~3.1.1"
@@ -3344,13 +3344,16 @@
"dev": true
},
"node_modules/array-buffer-byte-length": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
"integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
"integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"is-array-buffer": "^3.0.1"
"call-bind": "^1.0.5",
"is-array-buffer": "^3.0.4"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -3372,17 +3375,18 @@
}
},
"node_modules/arraybuffer.prototype.slice": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz",
"integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
"integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
"dev": true,
"dependencies": {
"array-buffer-byte-length": "^1.0.0",
"call-bind": "^1.0.2",
"define-properties": "^1.2.0",
"es-abstract": "^1.22.1",
"get-intrinsic": "^1.2.1",
"is-array-buffer": "^3.0.2",
"array-buffer-byte-length": "^1.0.1",
"call-bind": "^1.0.5",
"define-properties": "^1.2.1",
"es-abstract": "^1.22.3",
"es-errors": "^1.2.1",
"get-intrinsic": "^1.2.3",
"is-array-buffer": "^3.0.4",
"is-shared-array-buffer": "^1.0.2"
},
"engines": {
@@ -3479,9 +3483,9 @@
}
},
"node_modules/available-typed-arrays": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz",
"integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==",
"dev": true,
"engines": {
"node": ">= 0.4"
@@ -3533,29 +3537,13 @@
}
},
"node_modules/babel-plugin-polyfill-corejs3": {
"version": "0.8.7",
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz",
"integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==",
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz",
"integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==",
"dev": true,
"dependencies": {
"@babel/helper-define-polyfill-provider": "^0.4.4",
"core-js-compat": "^3.33.1"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
"node_modules/babel-plugin-polyfill-corejs3/node_modules/@babel/helper-define-polyfill-provider": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz",
"integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==",
"dev": true,
"dependencies": {
"@babel/helper-compilation-targets": "^7.22.6",
"@babel/helper-plugin-utils": "^7.22.5",
"debug": "^4.1.1",
"lodash.debounce": "^4.0.8",
"resolve": "^1.14.2"
"@babel/helper-define-polyfill-provider": "^0.5.0",
"core-js-compat": "^3.34.0"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -3833,9 +3821,9 @@
}
},
"node_modules/browserslist": {
"version": "4.22.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
"integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
"version": "4.22.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz",
"integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==",
"dev": true,
"funding": [
{
@@ -3852,8 +3840,8 @@
}
],
"dependencies": {
"caniuse-lite": "^1.0.30001565",
"electron-to-chromium": "^1.4.601",
"caniuse-lite": "^1.0.30001580",
"electron-to-chromium": "^1.4.648",
"node-releases": "^2.0.14",
"update-browserslist-db": "^1.0.13"
},
@@ -3903,14 +3891,18 @@
}
},
"node_modules/call-bind": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
"integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz",
"integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.1",
"set-function-length": "^1.1.1"
"get-intrinsic": "^1.2.3",
"set-function-length": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -3957,9 +3949,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001579",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz",
"integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==",
"version": "1.0.30001585",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001585.tgz",
"integrity": "sha512-yr2BWR1yLXQ8fMpdS/4ZZXpseBgE7o4g41x3a6AJOqZuOi+iE/WdJYAuZ6Y95i4Ohd2Y+9MzIWRR+uGABH4s3Q==",
"dev": true,
"funding": [
{
@@ -4029,16 +4021,10 @@
}
},
"node_modules/chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
],
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
@@ -4051,6 +4037,9 @@
"engines": {
"node": ">= 8.10.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
@@ -4343,9 +4332,9 @@
"dev": true
},
"node_modules/core-js-compat": {
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.0.tgz",
"integrity": "sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==",
"version": "3.35.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.1.tgz",
"integrity": "sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw==",
"dev": true,
"dependencies": {
"browserslist": "^4.22.2"
@@ -4741,14 +4730,15 @@
}
},
"node_modules/define-data-property": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
"integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz",
"integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==",
"dev": true,
"dependencies": {
"get-intrinsic": "^1.2.1",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.2",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0"
"has-property-descriptors": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -5014,9 +5004,9 @@
"dev": true
},
"node_modules/electron-to-chromium": {
"version": "1.4.639",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.639.tgz",
"integrity": "sha512-CkKf3ZUVZchr+zDpAlNLEEy2NJJ9T64ULWaDgy3THXXlPVPkLu3VOs9Bac44nebVtdwl2geSj6AxTtGDOxoXhg==",
"version": "1.4.659",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.659.tgz",
"integrity": "sha512-sRJ3nV3HowrYpBtPF9bASQV7OW49IgZC01Xiq43WfSE3RTCkK0/JidoCmR73Hyc1mN+l/H4Yqx0eNiomvExFZg==",
"dev": true
},
"node_modules/elliptic": {
@@ -5087,9 +5077,9 @@
}
},
"node_modules/envinfo": {
"version": "7.11.0",
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz",
"integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==",
"version": "7.11.1",
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz",
"integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==",
"dev": true,
"bin": {
"envinfo": "dist/cli.js"
@@ -5160,6 +5150,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-module-lexer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
@@ -5248,9 +5247,9 @@
}
},
"node_modules/escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
"dev": true,
"engines": {
"node": ">=6"
@@ -5549,9 +5548,9 @@
}
},
"node_modules/fastq": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz",
"integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==",
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
"integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
"dev": true,
"dependencies": {
"reusify": "^1.0.4"
@@ -6038,16 +6037,20 @@
}
},
"node_modules/get-intrinsic": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
"integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -6065,13 +6068,13 @@
}
},
"node_modules/get-symbol-description": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
"integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.1.tgz",
"integrity": "sha512-KmuibvwbWaM4BHcBRYwJfZ1JxyJeBwB8ct9YYu67SvYdbEIlcQ2e56dHxfbobqW38GXo8/zDFqJeGtHiVbWyQw==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.1.1"
"call-bind": "^1.0.5",
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
@@ -6246,12 +6249,12 @@
}
},
"node_modules/has-tostringtag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true,
"dependencies": {
"has-symbols": "^1.0.2"
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
@@ -6613,9 +6616,9 @@
]
},
"node_modules/ignore": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
"integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==",
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
"integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
"dev": true,
"engines": {
"node": ">= 4"
@@ -6732,12 +6735,12 @@
"dev": true
},
"node_modules/internal-slot": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz",
"integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
"integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
"dev": true,
"dependencies": {
"get-intrinsic": "^1.2.2",
"es-errors": "^1.3.0",
"hasown": "^2.0.0",
"side-channel": "^1.0.4"
},
@@ -6764,14 +6767,16 @@
}
},
"node_modules/is-array-buffer": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
"integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
"integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.0",
"is-typed-array": "^1.1.10"
"get-intrinsic": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -7044,12 +7049,12 @@
}
},
"node_modules/is-typed-array": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
"integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
"integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
"dev": true,
"dependencies": {
"which-typed-array": "^1.1.11"
"which-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
@@ -8429,9 +8434,9 @@
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz",
"integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==",
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
"integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
"dev": true,
"engines": {
"node": "14 || >=16.14"
@@ -8529,9 +8534,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.33",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
"integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
"version": "8.4.34",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.34.tgz",
"integrity": "sha512-4eLTO36woPSocqZ1zIrFD2K1v6wH7pY1uBh0JIM2KKfrVtGvPFiAku6aNOP0W1Wr9qwnaCsF0Z+CrVnryB2A8Q==",
"dev": true,
"funding": [
{
@@ -9220,9 +9225,9 @@
"dev": true
},
"node_modules/prettier": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
"integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@@ -9896,13 +9901,13 @@
]
},
"node_modules/safe-regex-test": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz",
"integrity": "sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
"integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.5",
"get-intrinsic": "^1.2.2",
"call-bind": "^1.0.6",
"es-errors": "^1.3.0",
"is-regex": "^1.1.4"
},
"engines": {
@@ -9956,9 +9961,9 @@
}
},
"node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -10136,14 +10141,15 @@
}
},
"node_modules/set-function-length": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz",
"integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz",
"integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==",
"dev": true,
"dependencies": {
"define-data-property": "^1.1.1",
"define-data-property": "^1.1.2",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.2",
"get-intrinsic": "^1.2.3",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.1"
},
@@ -10239,14 +10245,18 @@
"dev": true
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz",
"integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
"call-bind": "^1.0.6",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -10329,9 +10339,9 @@
}
},
"node_modules/spdx-exceptions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
"integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz",
"integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==",
"dev": true
},
"node_modules/spdx-expression-parse": {
@@ -11086,14 +11096,14 @@
}
},
"node_modules/typed-array-buffer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
"integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz",
"integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.1",
"is-typed-array": "^1.1.10"
"call-bind": "^1.0.6",
"es-errors": "^1.3.0",
"is-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
@@ -11429,19 +11439,19 @@
}
},
"node_modules/webpack": {
"version": "5.89.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz",
"integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==",
"version": "5.90.1",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.1.tgz",
"integrity": "sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==",
"dev": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.0",
"@types/estree": "^1.0.5",
"@webassemblyjs/ast": "^1.11.5",
"@webassemblyjs/wasm-edit": "^1.11.5",
"@webassemblyjs/wasm-parser": "^1.11.5",
"acorn": "^8.7.1",
"acorn-import-assertions": "^1.9.0",
"browserslist": "^4.14.5",
"browserslist": "^4.21.10",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.15.0",
"es-module-lexer": "^1.2.1",
@@ -11455,7 +11465,7 @@
"neo-async": "^2.6.2",
"schema-utils": "^3.2.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.3.7",
"terser-webpack-plugin": "^5.3.10",
"watchpack": "^2.4.0",
"webpack-sources": "^3.2.3"
},
@@ -11908,16 +11918,16 @@
}
},
"node_modules/which-typed-array": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz",
"integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==",
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz",
"integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==",
"dev": true,
"dependencies": {
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.4",
"available-typed-arrays": "^1.0.6",
"call-bind": "^1.0.5",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-tostringtag": "^1.0.0"
"has-tostringtag": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
+1 -1
View File
@@ -17,7 +17,7 @@
"illuminate/contracts": "^10.0|^11.0",
"illuminate/database": "^10.38|^11.0",
"illuminate/support": "^10.0|^11.0",
"league/csv": "9.11.0",
"league/csv": "^9.14",
"openspout/openspout": "^4.23",
"spatie/laravel-package-tools": "^1.9"
},
+1 -1
View File
@@ -293,7 +293,7 @@ Instead of opening in the center of the screen, the modal content will now slide
## Making the modal header sticky
The header of a modal scrolls out of view with the modal content when it overflows the modal size. However, slide-overs have a sticky modal that's always visible. You may control this behavior using `stickyModalHeader()`:
The header of a modal scrolls out of view with the modal content when it overflows the modal size. However, slide-overs have a sticky header that's always visible. You may control this behavior using `stickyModalHeader()`:
```php
Action::make('updateAuthor')
@@ -45,7 +45,7 @@ class ManagePost extends Component implements HasForms, HasActions
## Adding the action
Add a method that returns your action:
Add a method that returns your action. The method must share the exact same name as the action, or the name followed by `Action`:
```php
use App\Models\Post;
@@ -69,6 +69,12 @@ class ManagePost extends Component implements HasForms, HasActions
->requiresConfirmation()
->action(fn () => $this->post->delete());
}
// This method name also works, since the action name is `delete`:
// public function delete(): Action
// This method name does not work, since the action name is `delete`, not `deletePost`:
// public function deletePost(): Action
// ...
}
@@ -444,6 +444,15 @@ ImportColumn::make('sku')
->example('ABC123')
```
By default, the name of the column is used in the header of the example CSV. You can customize the header per-column using `exampleHeader()`:
```php
use Filament\Actions\Imports\ImportColumn;
ImportColumn::make('sku')
->exampleHeader('SKU')
```
## Using a custom user model
By default, the `imports` table has a `user_id` column. That column is constrained to the `users` table:
@@ -601,6 +610,17 @@ public function getJobTags(): array
If you'd like to customize the tags that are applied to jobs of a certain importer, you may override this method in your importer class.
### Customizing the import job batch name
By default, the import system doesn't define any name for the job batches. If you'd like to customize the name that is applied to job batches of a certain importer, you may override the `getJobBatchName()` method in your importer class:
```php
public function getJobBatchName(): ?string
{
return 'product-import';
}
```
## Customizing import validation messages
The import system will automatically validate the CSV file before it is imported. If there are any errors, the user will be shown a list of them, and the import will not be processed. If you'd like to override any default validation messages, you may do so by overriding the `getValidationMessages()` method on your importer class:
@@ -704,3 +724,30 @@ class ProductImporter extends Importer
Inside these hooks, you can access the current row's data using `$this->data`. You can also access the original row of data from the CSV, before it was [cast](#casting-state) or mapped, using `$this->originalData`.
The current record (if it exists yet) is accessible in `$this->record`, and the [import form options](#using-import-options) using `$this->options`.
## Authorization
By default, only the user who started the import may access the failure CSV file that gets generated if part of an import fails. If you'd like to customize the authorization logic, you may create an `ImportPolicy` class, and [register it in your `AuthServiceProvider`](https://laravel.com/docs/10.x/authorization#registering-policies):
```php
use App\Policies\ImportPolicy;
use Filament\Actions\Imports\Models\Import;
protected $policies = [
Import::class => ImportPolicy::class,
];
```
The `view()` method of the policy will be used to authorize access to the failure CSV file.
Please note that if you define a policy, the existing logic of ensuring only the user who started the import can access the failure CSV file will be removed. You will need to add that logic to your policy if you want to keep it:
```php
use App\Models\User;
use Filament\Actions\Imports\Models\Import;
public function view(User $user, Import $import): bool
{
return $import->user()->is($user);
}
```
@@ -111,6 +111,29 @@ ExportColumn::make('sku')
->label('SKU')
```
### Configuring the default column selection
By default, all columns will be selected when the user is asked which columns they would like to export. You can customize the default selection state for a column with the `enabledByDefault()` method:
```php
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('description')
->enabledByDefault(false)
```
### Disabling column selection
By default, user will be asked which columns they would like to export. You can disable this functionality using `columnMapping(false)`:
```php
use App\Filament\Exports\ProductExporter;
ExportAction::make()
->exporter(ProductExporter::class)
->columnMapping(false)
```
### Calculated export column state
Sometimes you need to calculate the state of a column, instead of directly reading it from a database column.
@@ -270,7 +293,6 @@ By default, the export action will allow the user to choose between both CSV and
```php
use App\Filament\Exports\ProductExporter;
use Filament\Actions\ExportAction;
use Filament\Actions\Exports\Enums\ExportFormat;
ExportAction::make()
@@ -302,6 +324,19 @@ public function getFormats(): array
}
```
## Modifying the export query
By default, if you are using the `ExportAction` with a table, the action will use the table's currently filtered and sorted query to export the data. If you don't have a table, it will use the model's default query. To modify the query builder before exporting, you can use the `modifyQueryUsing()` method on the action:
```php
use App\Filament\Exports\ProductExporter;
use Illuminate\Database\Eloquent\Builder;
ExportAction::make()
->exporter(ProductExporter::class)
->modifyQueryUsing(fn (Builder $query) => $query->where('is_active', true))
```
## Configuring the export filesystem
### Customizing the storage disk
@@ -311,8 +346,6 @@ By default, exported files will be uploaded to the storage disk defined in the [
If you want to use a different disk for a specific export, you can pass the disk name to the `disk()` method on the action:
```php
use Filament\Actions\ExportAction;
ExportAction::make()
->exporter(ProductExporter::class)
->fileDisk('s3')
@@ -332,7 +365,6 @@ public function getFileDisk(): string
By default, exported files will have a name generated based on the ID and type of the export. You can also use the `fileName()` method on the action to customize the file name:
```php
use Filament\Actions\ExportAction;
use Filament\Actions\Exports\Models\Export;
ExportAction::make()
@@ -372,8 +404,6 @@ public static function getOptionsFormComponents(): array
Alternatively, you can pass a set of static options to the exporter through the `options()` method on the action:
```php
use Filament\Actions\ExportAction;
ExportAction::make()
->exporter(ProductExporter::class)
->options([
@@ -558,3 +588,41 @@ public function getJobTags(): array
```
If you'd like to customize the tags that are applied to jobs of a certain exporter, you may override this method in your exporter class.
### Customizing the export job batch name
By default, the export system doesn't define any name for the job batches. If you'd like to customize the name that is applied to job batches of a certain exporter, you may override the `getJobBatchName()` method in your exporter class:
```php
public function getJobBatchName(): ?string
{
return 'product-export';
}
```
## Authorization
By default, only the user who started the export may download files that get generated. If you'd like to customize the authorization logic, you may create an `ExportPolicy` class, and [register it in your `AuthServiceProvider`](https://laravel.com/docs/10.x/authorization#registering-policies):
```php
use App\Policies\ExportPolicy;
use Filament\Actions\Exports\Models\Export;
protected $policies = [
Export::class => ExportPolicy::class,
];
```
The `view()` method of the policy will be used to authorize access to the downloads.
Please note that if you define a policy, the existing logic of ensuring only the user who started the export can access it will be removed. You will need to add that logic to your policy if you want to keep it:
```php
use App\Models\User;
use Filament\Actions\Exports\Models\Export;
public function view(User $user, Export $export): bool
{
return $export->user()->is($user);
}
```
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'تصدير :label',
'modal' => [
'heading' => 'تصدير :label',
'form' => [
'columns' => [
'label' => 'العواميد',
'form' => [
'is_enabled' => [
'label' => ':column مفعل',
],
'label' => [
'label' => ':column عنوان',
],
],
],
],
'actions' => [
'export' => [
'label' => 'تصدير',
],
],
],
'notifications' => [
'completed' => [
'title' => 'أكتمل التصدير',
'actions' => [
'download_csv' => [
'label' => 'تحميل بصيغة .csv',
],
'download_xlsx' => [
'label' => 'تحميل بصيغة .xlsx',
],
],
],
'max_rows' => [
'title' => 'الملف الذي تم تحميله كبير جدًا',
'body' => 'لا يمكنك تصدير أكثر من صف واحد في كل مرة.|لا يمكنك تصدير أكثر من :count صف في كل مرة.',
],
'started' => [
'title' => 'بدء التصدير',
'body' => 'بدأت عملية التصدير الخاصة بك وستتم معالجة صف واحد في الخلفية.|بدأت عملية التصدير الخاصة بك وستتم معالجة :count صفوف في الخلفية.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -12,7 +12,7 @@ return [
'actions' => [
'detach' => [
'dissociate' => [
'label' => 'Odvojite',
],
@@ -22,7 +22,7 @@ return [
'notifications' => [
'detached' => [
'dissociated' => [
'title' => 'Odvojeno',
],
@@ -40,7 +40,7 @@ return [
'actions' => [
'detach' => [
'dissociate' => [
'label' => 'Odvojite izabrani',
],
@@ -50,7 +50,7 @@ return [
'notifications' => [
'detached' => [
'dissociated' => [
'title' => 'Odvojeno',
],
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Exportar :label',
'modal' => [
'heading' => 'Exportar :label',
'form' => [
'columns' => [
'label' => 'Columnes',
'form' => [
'is_enabled' => [
'label' => ':column habilitada',
],
'label' => [
'label' => 'etiqueta per a :column',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Exportar',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Exportació completada',
'actions' => [
'download_csv' => [
'label' => 'Descarregar .csv',
],
'download_xlsx' => [
'label' => 'Descarregar .xlsx',
],
],
],
'max_rows' => [
'title' => 'L\'exportació és massa gran',
'body' => 'No es pot exportar més d\'una fila alhora.|No es poden exportar més de :count files alhora.',
],
'started' => [
'title' => 'Exportació iniciada',
'body' => 'L\'exportació ha començat i es processarà una fila en segon pla.|L\'exportació ha començat i es processaran :count files en segon pla.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Exportovat :label',
'modal' => [
'heading' => 'Exportovat :label',
'form' => [
'columns' => [
'label' => 'Sloupce',
'form' => [
'is_enabled' => [
'label' => ':column povoleno',
],
'label' => [
'label' => ':column popisek',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Exportovat',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Export dokončen',
'actions' => [
'download_csv' => [
'label' => 'Stáhnout .csv',
],
'download_xlsx' => [
'label' => 'Stáhnout .xlsx',
],
],
],
'max_rows' => [
'title' => 'Export překračuje povolenou velikost',
'body' => 'Není možné exportovat více než 1 řádek najednou.|Není možné exportovat více než :count řádků najednou.',
],
'started' => [
'title' => 'Export byl zahájen',
'body' => 'Export byl zahájen a 1 řádek bude zpracován na pozadí.|Váš export byl zahájen a :count řádků bude zpracováno na pozadí.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Exportiere :label',
'modal' => [
'heading' => 'Exportiere :label',
'form' => [
'columns' => [
'label' => 'Spalten',
'form' => [
'is_enabled' => [
'label' => ':column ist aktiviert',
],
'label' => [
'label' => ':column Beschriftung',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Export',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Export abgeschlossen',
'actions' => [
'download_csv' => [
'label' => 'Lade .csv herunter',
],
'download_xlsx' => [
'label' => 'Lade .xlsx herunter',
],
],
],
'max_rows' => [
'title' => 'Der Export ist zu groß',
'body' => 'Nicht mehr als 1 Zeile auf einmal exportieren.|Nicht mehr als :count Zeilen auf einmal exportieren.',
],
'started' => [
'title' => 'Export gestartet',
'body' => 'Der Export wurde gestartet und 1 Zeile wird im Hintergrund verarbeitet.| Der Export wurde gestartet und :count Zeilen werden im Hintergrund verarbeitet.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => ':label Import',
'modal' => [
'heading' => ':label Import',
'form' => [
'file' => [
'label' => 'Datei',
'placeholder' => 'CSV Datei hochladen',
],
'columns' => [
'label' => 'Spalten',
'placeholder' => 'Spalte auswählen',
],
],
'actions' => [
'download_example' => [
'label' => 'Lade Beispiel CSV herunter',
],
'import' => [
'label' => 'Importieren',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Import abgeschlossen',
'actions' => [
'download_failed_rows_csv' => [
'label' => 'Informationen über die fehlgeschlagene Zeile herunterladen|Informationen über die fehlgeschlagenen Zeilen herunterladen',
],
],
],
'max_rows' => [
'title' => 'CSV Datei ist zu groß',
'body' => 'Nicht mehr als 1 Zeile auf einmal importieren.|Nicht mehr als :count Zeilen auf einmal importieren.',
],
'started' => [
'title' => 'Import gestartet',
'body' => 'Der Import wurde gestartet und 1 Zeile wird im Hintergrund verarbeitet.|Der Import wurde gestartet und :count Zeilen werden im Hintergrund verarbeitet.',
],
],
'example_csv' => [
'file_name' => ':importer-example',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-failed-rows',
'error_header' => 'Fehler',
'system_error' => 'Systemfehler, bitte Supportanfrage stellen.',
],
];
@@ -0,0 +1,45 @@
<?php
return [
'single' => [
'label' => 'Συσχέτιση',
'modal' => [
'heading' => 'Associate :label',
'fields' => [
'record_id' => [
'label' => 'Record',
],
],
'actions' => [
'associate' => [
'label' => 'Associate',
],
'associate_another' => [
'label' => 'Associate & associate another',
],
],
],
'notifications' => [
'associated' => [
'title' => 'Associated',
],
],
],
];
@@ -0,0 +1,45 @@
<?php
return [
'single' => [
'label' => 'Attach',
'modal' => [
'heading' => 'Attach :label',
'fields' => [
'record_id' => [
'label' => 'Record',
],
],
'actions' => [
'attach' => [
'label' => 'Attach',
],
'attach_another' => [
'label' => 'Attach & attach another',
],
],
],
'notifications' => [
'attached' => [
'title' => 'Attached',
],
],
],
];
@@ -0,0 +1,37 @@
<?php
return [
'single' => [
'label' => 'Προσθήκη :label',
'modal' => [
'heading' => 'Δημιουργία :label',
'actions' => [
'create' => [
'label' => 'Δημιουργία',
],
'create_another' => [
'label' => 'Δημιουργία & δημιουργία νέου',
],
],
],
'notifications' => [
'created' => [
'title' => 'Δημιουργήθηκε επιτυχώς',
],
],
],
];
@@ -0,0 +1,61 @@
<?php
return [
'single' => [
'label' => 'Διαγραφή',
'modal' => [
'heading' => 'Διαγραφή :label',
'actions' => [
'delete' => [
'label' => 'Διαγραφή',
],
],
],
'notifications' => [
'deleted' => [
'title' => 'Διαγράφηκε επιτυχώς',
],
],
],
'multiple' => [
'label' => 'Διαγραφή επιλεγμένων',
'modal' => [
'heading' => 'Διαγραφή επιλεγμένων :label',
'actions' => [
'delete' => [
'label' => 'Διαγραφή',
],
],
],
'notifications' => [
'deleted' => [
'title' => 'Διαγράφηκαν επιτυχώς',
],
],
],
];
@@ -0,0 +1,61 @@
<?php
return [
'single' => [
'label' => 'Detach',
'modal' => [
'heading' => 'Detach :label',
'actions' => [
'detach' => [
'label' => 'Detach',
],
],
],
'notifications' => [
'detached' => [
'title' => 'Detached',
],
],
],
'multiple' => [
'label' => 'Detach selected',
'modal' => [
'heading' => 'Detach selected :label',
'actions' => [
'detach' => [
'label' => 'Detach',
],
],
],
'notifications' => [
'detached' => [
'title' => 'Detached',
],
],
],
];
@@ -0,0 +1,61 @@
<?php
return [
'single' => [
'label' => 'Dissociate',
'modal' => [
'heading' => 'Dissociate :label',
'actions' => [
'dissociate' => [
'label' => 'Dissociate',
],
],
],
'notifications' => [
'dissociated' => [
'title' => 'Dissociated',
],
],
],
'multiple' => [
'label' => 'Dissociate selected',
'modal' => [
'heading' => 'Dissociate selected :label',
'actions' => [
'dissociate' => [
'label' => 'Dissociate',
],
],
],
'notifications' => [
'dissociated' => [
'title' => 'Dissociated',
],
],
],
];
@@ -0,0 +1,33 @@
<?php
return [
'single' => [
'label' => 'Επεξεργασία',
'modal' => [
'heading' => 'Επεξεργασία :label',
'actions' => [
'save' => [
'label' => 'Αποθήκευση αλλαγών',
],
],
],
'notifications' => [
'saved' => [
'title' => 'Η αποθήκευση ολοκληρώθηκε',
],
],
],
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Export :label',
'modal' => [
'heading' => 'Export :label',
'form' => [
'columns' => [
'label' => 'Columns',
'form' => [
'is_enabled' => [
'label' => ':column enabled',
],
'label' => [
'label' => ':column label',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Export',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Export completed',
'actions' => [
'download_csv' => [
'label' => 'Download .csv',
],
'download_xlsx' => [
'label' => 'Download .xlsx',
],
],
],
'max_rows' => [
'title' => 'Export is too large',
'body' => 'You may not export more than 1 row at once.|You may not export more than :count rows at once.',
],
'started' => [
'title' => 'Export started',
'body' => 'Your export has begun and 1 row will be processed in the background.|Your export has begun and :count rows will be processed in the background.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,61 @@
<?php
return [
'single' => [
'label' => 'Καθολική διαγραφή',
'modal' => [
'heading' => 'Καθολική διαγραφή :label',
'actions' => [
'delete' => [
'label' => 'Διαγραφή',
],
],
],
'notifications' => [
'deleted' => [
'title' => 'Διαγράφηκε επιτυχώς',
],
],
],
'multiple' => [
'label' => 'Καθολική διαγραφή επιλεγμένων',
'modal' => [
'heading' => 'Καθολική διαγραφή επιλεγμένων :label',
'actions' => [
'delete' => [
'label' => 'Διαγραφή',
],
],
],
'notifications' => [
'deleted' => [
'title' => 'Διαγράφηκαν επιτυχώς',
],
],
],
];
@@ -0,0 +1,9 @@
<?php
return [
'trigger' => [
'label' => 'Actions',
],
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Import :label',
'modal' => [
'heading' => 'Import :label',
'form' => [
'file' => [
'label' => 'File',
'placeholder' => 'Upload a CSV file',
],
'columns' => [
'label' => 'Columns',
'placeholder' => 'Select a column',
],
],
'actions' => [
'download_example' => [
'label' => 'Download example CSV file',
],
'import' => [
'label' => 'Import',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Import completed',
'actions' => [
'download_failed_rows_csv' => [
'label' => 'Download information about the failed row|Download information about the failed rows',
],
],
],
'max_rows' => [
'title' => 'Uploaded CSV file is too large',
'body' => 'You may not import more than 1 row at once.|You may not import more than :count rows at once.',
],
'started' => [
'title' => 'Import started',
'body' => 'Your import has begun and 1 row will be processed in the background.|Your import has begun and :count rows will be processed in the background.',
],
],
'example_csv' => [
'file_name' => ':importer-example',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-failed-rows',
'error_header' => 'error',
'system_error' => 'System error, please contact support.',
],
];
@@ -0,0 +1,23 @@
<?php
return [
'confirmation' => "Είστε σίγουρος/η γι' αυτή την ενέργεια;",
'actions' => [
'cancel' => [
'label' => 'Άκυρο',
],
'confirm' => [
'label' => 'Επιβεβαίωση',
],
'submit' => [
'label' => 'Submit',
],
],
];
@@ -0,0 +1,33 @@
<?php
return [
'single' => [
'label' => 'Αντιγραφή',
'modal' => [
'heading' => 'Αντιγραφή :label',
'actions' => [
'replicate' => [
'label' => 'Αντιγραφή',
],
],
],
'notifications' => [
'replicated' => [
'title' => 'Αντιγράφηκε επιτυχώς',
],
],
],
];
@@ -0,0 +1,61 @@
<?php
return [
'single' => [
'label' => 'Επαναφορά',
'modal' => [
'heading' => 'Επαναφορά :label',
'actions' => [
'restore' => [
'label' => 'Επαναφορά',
],
],
],
'notifications' => [
'restored' => [
'title' => 'Έγινε επιτυχής επαναφορά',
],
],
],
'multiple' => [
'label' => 'Επαναφορά επιλεγμένων',
'modal' => [
'heading' => 'Επαναφορά επιλεγμένων :label',
'actions' => [
'restore' => [
'label' => 'Επαναφορά',
],
],
],
'notifications' => [
'restored' => [
'title' => 'Έγινε επιτυχής επαναφορά',
],
],
],
];
@@ -0,0 +1,25 @@
<?php
return [
'single' => [
'label' => 'Προβολή',
'modal' => [
'heading' => 'Προβολή :label',
'actions' => [
'close' => [
'label' => 'Άκυρο',
],
],
],
],
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'اکسپورت :label',
'modal' => [
'heading' => 'اکسپورت :label',
'form' => [
'columns' => [
'label' => 'ستون ها',
'form' => [
'is_enabled' => [
'label' => ':ستون فعال است',
],
'label' => [
'label' => ':برچسب ستونی',
],
],
],
],
'actions' => [
'export' => [
'label' => 'اکسپورت',
],
],
],
'notifications' => [
'completed' => [
'title' => 'اکسپورت انجام شد',
'actions' => [
'download_csv' => [
'label' => 'دانلود csv.',
],
'download_xlsx' => [
'label' => 'دانلود xlsx.',
],
],
],
'max_rows' => [
'title' => 'اکسپورت خیلی بزرگ است',
'body' => 'شما نمی توانید بیش از 1 ردیف را به طور همزمان صادر کنید.|شما نمی توانید بیش از :count ردیف ها را همزمان صادر کنید.',
],
'started' => [
'title' => 'اکسپورت آغاز شد',
'body' => 'اکسپورت شما آغاز شده است و 1 ردیف در پس‌زمینه پردازش می‌شود.|اکسپورت شما آغاز شده است و ردیف‌های :count در پس‌زمینه پردازش می‌شوند.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'ایمپورت :label',
'modal' => [
'heading' => 'ایمپورت :label',
'form' => [
'file' => [
'label' => 'پرونده',
'placeholder' => 'آپلود یک فایل CSV',
],
'columns' => [
'label' => 'ستون ها',
'placeholder' => 'یک ستون را انتخاب کنید',
],
],
'actions' => [
'download_example' => [
'label' => 'دانلود نمونه فایل CSV',
],
'import' => [
'label' => 'ایمپورت',
],
],
],
'notifications' => [
'completed' => [
'title' => 'ایمپورت تکمیل شد',
'actions' => [
'download_failed_rows_csv' => [
'label' => 'دانلود اطلاعات در مورد ردیف ناموفق|دانلود اطلاعات در مورد ردیف های ناموفق',
],
],
],
'max_rows' => [
'title' => 'فایل CSV آپلود شده خیلی بزرگ است',
'body' => 'شما نمی توانید بیش از 1 ردیف را به طور همزمان وارد کنید.|شما نمی توانید بیش از :count ردیف ها را در یک زمان وارد کنید.',
],
'started' => [
'title' => 'ایمپورت آغاز شد',
'body' => 'ایمپورت شما شروع شده است و 1 ردیف در پس‌زمینه پردازش می‌شود.|ایمپورت شما آغاز شده است و ردیف‌های :count در پس‌زمینه پردازش می‌شوند.',
],
],
'example_csv' => [
'file_name' => ':importer-example',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-failed-rows',
'error_header' => 'خطا',
'system_error' => 'خطای سیستمی, لطفا با پشتیبانی تماس بگیرید.',
],
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Exporter :label',
'modal' => [
'heading' => 'Exporter :label',
'form' => [
'columns' => [
'label' => 'Colonnes',
'form' => [
'is_enabled' => [
'label' => ':column sélectionnée',
],
'label' => [
'label' => ':column label',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Exporter',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Exportation terminée',
'actions' => [
'download_csv' => [
'label' => 'Télécharger .csv',
],
'download_xlsx' => [
'label' => 'Télécharger .xlsx',
],
],
],
'max_rows' => [
'title' => 'L\'exportation est trop volumineuse',
'body' => 'Vous ne pouvez pas exporter plus d’une ligne à la fois.|Vous ne pouvez pas exporter plus de :count lignes à la fois',
],
'started' => [
'title' => 'L’exportation a commencé',
'body' => 'Votre exportation a commencé et 1 ligne sera traitée en arrière-plan.|Votre exportation a commencé et :count lignes seront traitées en arrière-plan.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => ':label exportálása',
'modal' => [
'heading' => ':label exportálása',
'form' => [
'columns' => [
'label' => 'Oszlopok',
'form' => [
'is_enabled' => [
'label' => ':column bekapcsolva',
],
'label' => [
'label' => ':column fejléc',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Exportálás',
],
],
],
'notifications' => [
'completed' => [
'title' => 'AZ exportálás befejeződött',
'actions' => [
'download_csv' => [
'label' => 'CSV letöltése',
],
'download_xlsx' => [
'label' => 'XLSX letöltése',
],
],
],
'max_rows' => [
'title' => 'Túl sok exportálandó sor',
'body' => 'Nem exportálhatsz több mint 1 sort egyszerre.|Nem exportálhatsz több mint :count sor egyszerre.',
],
'started' => [
'title' => 'Az exportálás elkezdődött',
'body' => 'Elkezdődött 1 exportálása a háttérben.|Elkezdődött :count sor exportálása a háttérben.',
],
],
'file_name' => 'exportálás-:export_id-:model',
];
@@ -66,7 +66,7 @@ return [
],
'started' => [
'title' => 'Export started',
'title' => 'Ekspor dimulai',
'body' => 'Mulai mengekspor :count baris dan proses akan berjalan di belakang layar.',
],
@@ -58,7 +58,7 @@ return [
],
'started' => [
'title' => 'Import started',
'title' => 'Impor dimulai',
'body' => 'Mulai mengimpor :count baris dan proses akan berjalan di belakang layar.',
],
@@ -70,7 +70,7 @@ return [
'failure_csv' => [
'file_name' => 'impor-:import_id-:csv_name-gagal',
'error_header' => 'error',
'error_header' => 'kesalahan',
'system_error' => 'Terjadi kesalahan sistem, harap hubungi tim support.',
],
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Eksport :label',
'modal' => [
'heading' => 'Eksport :label',
'form' => [
'columns' => [
'label' => 'Kolum',
'form' => [
'is_enabled' => [
'label' => ':column diaktifkan',
],
'label' => [
'label' => ':column label',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Eksport',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Eksport selesai',
'actions' => [
'download_csv' => [
'label' => 'Muat turun .csv',
],
'download_xlsx' => [
'label' => 'Muat turun .xlsx',
],
],
],
'max_rows' => [
'title' => 'Eksport terlalu besar',
'body' => 'Anda tidak boleh mengeluarkan lebih dari 1 baris pada satu masa.|Anda tidak boleh mengeluarkan lebih dari :count baris pada satu masa.',
],
'started' => [
'title' => 'Eksport bermula',
'body' => 'Eksport anda telah bermula dan 1 baris akan diproses di belakang tabir.|Eksport anda telah bermula dan :count baris akan diproses di belakang tabir.',
],
],
'file_name' => 'eksport-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Eksportuj :label',
'modal' => [
'heading' => 'Eksportuj :label',
'form' => [
'columns' => [
'label' => 'Kolumny',
'form' => [
'is_enabled' => [
'label' => ':column włączony',
],
'label' => [
'label' => 'Etykieta :column',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Eksportuj',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Eksport zakończony',
'actions' => [
'download_csv' => [
'label' => 'Pobierz .csv',
],
'download_xlsx' => [
'label' => 'Pobierz .xlsx',
],
],
],
'max_rows' => [
'title' => 'Zbyt dużo wierszy',
'body' => 'Nie możesz wyeksportować więcej niż 1 wiersz na raz.|Nie możesz wyeksportować więcej niż :count wierszy na raz.',
],
'started' => [
'title' => 'Eksport rozpoczęty',
'body' => 'Rozpoczęto eksport i 1 wiersz zostanie przetworzony w tle.|Rozpoczęto eksport i :count wierszy zostanie przetworzonych w tle.',
],
],
'file_name' => 'eksport-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Importuj :label',
'modal' => [
'heading' => 'Importuj :label',
'form' => [
'file' => [
'label' => 'Plik',
'placeholder' => 'Wybierz plik CSV',
],
'columns' => [
'label' => 'Kolumny',
'placeholder' => 'Wybierz kolumnę',
],
],
'actions' => [
'download_example' => [
'label' => 'Pobierz przykładowy plik CSV',
],
'import' => [
'label' => 'Importuj',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Import zakończony',
'actions' => [
'download_failed_rows_csv' => [
'label' => 'Pobierz informacje o niepowodzeniach',
],
],
],
'max_rows' => [
'title' => 'Przesłany plik CSV jest zbyt duży',
'body' => 'Nie możesz zaimportować więcej niż 1 wiersz na raz.|Nie możesz zaimportować więcej niż :count wierszy na raz.',
],
'started' => [
'title' => 'Import rozpoczęty',
'body' => 'Import rozpoczęty i 1 wiersz zostanie przetworzony w tle.|Import rozpoczęty i :count wierszy zostanie przetworzonych w tle.',
],
],
'example_csv' => [
'file_name' => ':importer-example',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-failed-rows',
'error_header' => 'błąd',
'system_error' => 'Błąd systemu, skontaktuj się z pomocą techniczną.',
],
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Exportă :label',
'modal' => [
'heading' => 'Exportă :label',
'form' => [
'columns' => [
'label' => 'Coloane',
'form' => [
'is_enabled' => [
'label' => ':column activat',
],
'label' => [
'label' => 'Eticheta :column',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Exportă',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Export complet',
'actions' => [
'download_csv' => [
'label' => 'Descarcă .csv',
],
'download_xlsx' => [
'label' => 'Descarcă .xlsx',
],
],
],
'max_rows' => [
'title' => 'Exportul este prea mare',
'body' => 'Nu puteți exporta mai mult de 1 rând odată.|Nu puteți exporta mai mult de :count rânduri odată',
],
'started' => [
'title' => 'Exportul a început',
'body' => 'Exportul dvs. a început și 1 rând va fi procesat în fundal.|Exportul dvs. a început și :count rânduri vor fi procesate în fundal.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Importă :label',
'modal' => [
'heading' => 'Importă :label',
'form' => [
'file' => [
'label' => 'Fișier',
'placeholder' => 'Încarcă un fișier CSV',
],
'columns' => [
'label' => 'Coloane',
'placeholder' => 'Alege Coloanele',
],
],
'actions' => [
'download_example' => [
'label' => 'Descarcă exemplu în format CSV',
],
'import' => [
'label' => 'Importă',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Import finalizat',
'actions' => [
'download_failed_rows_csv' => [
'label' => 'Descarcă informațiiler despre câmpul ce a avut eroaro|Descarcă informații despre câmpurile ce au auvt erori',
],
],
],
'max_rows' => [
'title' => 'Fișierul CSV file este prea mare',
'body' => 'Nu este permis importul a mai mult de o linile într-un singur fișier.|Nu este permis imporutl a mai mult de :count linii într-un singur fișier.',
],
'started' => [
'title' => 'Importul a început',
'body' => 'Importul dumneavostră a început, iar rândul va fi procesa în fundal.|Importul dumneavoastră a început, iar cele :count rânduri vor fi procesate în fundal.',
],
],
'example_csv' => [
'file_name' => ':importer-example',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-câmpuri-gresite',
'error_header' => 'error',
'system_error' => 'Eroare de sistem, vă rugăm contactați echipa de suport.',
],
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Экспорт :label',
'modal' => [
'heading' => 'Экспорт :label',
'form' => [
'columns' => [
'label' => 'Столбцы',
'form' => [
'is_enabled' => [
'label' => ':column включено',
],
'label' => [
'label' => ':column метка',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Экспорт',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Экспорт завершен',
'actions' => [
'download_csv' => [
'label' => 'Скачать .csv',
],
'download_xlsx' => [
'label' => 'Скачать .xlsx',
],
],
],
'max_rows' => [
'title' => 'Экспорт слишком велик',
'body' => 'Вы не можете экспортировать более 1 строки одновременно.|Вы не можете экспортировать более :count строк одновременно.',
],
'started' => [
'title' => 'Экспорт начался',
'body' => 'Ваш экспорт начался, и 1 строка будет обработана в фоновом режиме.|Ваш экспорт начался, и :count строк будет обработан в фоновом режиме.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Импорт :label',
'modal' => [
'heading' => 'Импорт :label',
'form' => [
'file' => [
'label' => 'Файл',
'placeholder' => 'Загрузить CSV-файл',
],
'columns' => [
'label' => 'Столбцы',
'placeholder' => 'Выберите столбец',
],
],
'actions' => [
'download_example' => [
'label' => 'Скачать пример CSV-файла',
],
'import' => [
'label' => 'Импорт',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Импорт завершен',
'actions' => [
'download_failed_rows_csv' => [
'label' => 'Загрузить информацию о неудавшейся строке|Загрузить информацию о неудавшейся строке',
],
],
],
'max_rows' => [
'title' => 'Загруженный файл CSV слишком велик.',
'body' => 'Вы не можете импортировать более 1 строки одновременно.|Вы не можете импортировать более :count строк одновременно.',
],
'started' => [
'title' => 'Импорт начался',
'body' => 'Ваш импорт начался, и 1 строка будет обработана в фоновом режиме.|Ваш импорт начался, и :count строк будет обрабатываться в фоновом режиме.',
],
],
'example_csv' => [
'file_name' => ':importer-example',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-failed-rows',
'error_header' => 'Ошибка',
'system_error' => 'Системная ошибка, обратитесь в службу поддержки.',
],
];
@@ -17,7 +17,7 @@ return [
],
'create_another' => [
'label' => 'Oluştur ve başka bir tane oluştur',
'label' => 'Oluştur & yeni oluştur',
],
],
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Dışa Aktar :label',
'modal' => [
'heading' => 'Dışa Aktar :label',
'form' => [
'columns' => [
'label' => 'Sütunlar',
'form' => [
'is_enabled' => [
'label' => ':column etkin',
],
'label' => [
'label' => ':column etiketi',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Dışa Aktar',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Dışa Aktarım Tamamlandı',
'actions' => [
'download_csv' => [
'label' => '.csv Olarak İndir',
],
'download_xlsx' => [
'label' => '.xlsx Olarak İndir',
],
],
],
'max_rows' => [
'title' => 'Maksimum Satır Sayısı Aşıldı',
'body' => 'Birden fazla satırı dışa aktaramazsınız.|:count satırı dışa aktaramazsınız.',
],
'started' => [
'title' => 'Dışa Aktarım Başladı',
'body' => 'Dışa aktarım başladı ve 1 satır arka planda işlenecek.|Dışa aktarım başladı ve :count satır arka planda işlenecek.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'İçe Aktar: :label',
'modal' => [
'heading' => 'İçe Aktar: :label',
'form' => [
'file' => [
'label' => 'Dosya',
'placeholder' => 'Bir CSV dosyası seçin',
],
'columns' => [
'label' => 'Kolonlar',
'placeholder' => 'Kolonları eşleştirin',
],
],
'actions' => [
'download_example' => [
'label' => 'Örnek CSV Dosyasını İndir',
],
'import' => [
'label' => 'İçe Aktar',
],
],
],
'notifications' => [
'completed' => [
'title' => 'İçe Aktarım Tamamlandı',
'actions' => [
'download_failed_rows_csv' => [
'label' => 'Başarısız satır hakkında bilgileri indir|Başarısız satırlar hakkında bilgileri indir',
],
],
],
'max_rows' => [
'title' => 'Yüklenen Dosya Çok Büyük',
'body' => 'Aynı anda 1\'den fazla satır içeren dosyaları içe aktaramazsınız.|Aynı anda :count\'den fazla satır içeren dosyaları içe aktaramazsınız.',
],
'started' => [
'title' => 'İçe Aktarım Başladı',
'body' => 'İçe aktarım başladı ve 1 satır arka planda işlenecek.|İçe aktarım başladı ve :count satır arka planda işlenecek.',
],
],
'example_csv' => [
'file_name' => ':importer-example',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-failed-rows',
'error_header' => 'hata',
'system_error' => 'Sistem Hatası',
],
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Експорт :label',
'modal' => [
'heading' => 'Експорт :label',
'form' => [
'columns' => [
'label' => 'Стовпці',
'form' => [
'is_enabled' => [
'label' => ':стовпець увімкнено',
],
'label' => [
'label' => ':column мітка',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Експорт',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Експорт завершено',
'actions' => [
'download_csv' => [
'label' => 'Завантажити .csv',
],
'download_xlsx' => [
'label' => 'Завантажити .xlsx',
],
],
],
'max_rows' => [
'title' => 'Експорт занадто великий',
'body' => 'Ви не можете експортувати більше 1 рядка одночасно.|Ви не можете експортувати більше :count рядків одночасно.',
],
'started' => [
'title' => 'Експорт розпочався',
'body' => 'Ваш експорт почався, і 1 рядок буде оброблено у фоновому режимі.|Ваш експорт почався, і :count рядків буде оброблено у фоновому режимі.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Імпорт :label',
'modal' => [
'heading' => 'Імпорт :label',
'form' => [
'file' => [
'label' => 'Файл',
'placeholder' => 'Завантажити CSV-файл',
],
'columns' => [
'label' => 'Стовпці',
'placeholder' => 'Виберіть стовпець',
],
],
'actions' => [
'download_example' => [
'label' => 'Завантажити приклад CSV-файлу',
],
'import' => [
'label' => 'Імпорт',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Імпорт завершено',
'actions' => [
'download_failed_rows_csv' => [
'label' => 'Завантажити інформацію про невдалий рядок|Завантажити інформацію про невдалий рядок',
],
],
],
'max_rows' => [
'title' => 'Завантажений файл CSV занадто великий.',
'body' => 'Ви не можете імпортувати більше 1 рядка одночасно.|Ви не можете імпортувати більше :count рядків одночасно.',
],
'started' => [
'title' => 'Імпорт розпочався',
'body' => 'Ваш імпорт розпочався, і 1 рядок буде опрацьовано у фоновому режимі.|Ваш імпорт розпочався, і :count рядків буде опрацьовуватися у фоновому режимі.',
],
],
'example_csv' => [
'file_name' => ':importer-example',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-failed-rows',
'error_header' => 'Помилка',
'system_error' => 'Системна помилка, зверніться до служби підтримки.',
],
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Xuất :label',
'modal' => [
'heading' => 'Xuất :label',
'form' => [
'columns' => [
'label' => 'Cột',
'form' => [
'is_enabled' => [
'label' => ':column đã kích hoạt',
],
'label' => [
'label' => ':column nhãn',
],
],
],
],
'actions' => [
'export' => [
'label' => 'Xuất',
],
],
],
'notifications' => [
'completed' => [
'title' => 'Xuất đã hoàn thành',
'actions' => [
'download_csv' => [
'label' => 'Tải xuống .csv',
],
'download_xlsx' => [
'label' => 'Tải xuống .xlsx',
],
],
],
'max_rows' => [
'title' => 'Xuất quá lớn',
'body' => 'Bạn không thể xuất nhiều hơn 1 hàng cùng lúc.|Bạn không thể xuất nhiều hơn :count hàng cùng lúc.',
],
'started' => [
'title' => 'Xuất đã bắt đầu',
'body' => 'Quá trình xuất của bạn đã bắt đầu và 1 hàng sẽ được xử lý ở nền.|Quá trình xuất của bạn đã bắt đầu và :count hàng sẽ được xử lý ở nền.',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -49,27 +49,28 @@ return [
],
'max_rows' => [
'title' => '上传的 CSV 文件过大',
'body' => '你不能够一次性导入超过 1 行记录。|你不能够一次性导入超过 :count 行记录。',
],
'started' => [
'title' => '导入开始',
'body' => '你的导入已经开始,共 1 行将在后台处理。|你的导入已经开始,共 :count 行将在后台处理。',
],
],
'example_csv' => [
'file_name' => ':importer-example',
'max_rows' => [
'title' => '上传的 CSV 文件过大',
'body' => '你不能够一次性导入超过 1 行记录。|你不能够一次性导入超过 :count 行记录。',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-failed-rows',
'error_header' => '错误',
'system_error' => '系统错误,请联系支持。',
'started' => [
'title' => '导入开始',
'body' => '你的导入已经开始,共 1 行将在后台处理。|你的导入已经开始,共 :count 行将在后台处理。',
],
],
'example_csv' => [
'file_name' => ':importer-example',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-failed-rows',
'error_header' => '错误',
'system_error' => '系统错误,请联系支持。',
],
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => '匯出 :label',
'modal' => [
'heading' => '匯出 :label',
'form' => [
'columns' => [
'label' => '欄位',
'form' => [
'is_enabled' => [
'label' => ':column 開啟',
],
'label' => [
'label' => ':column 標籤',
],
],
],
],
'actions' => [
'export' => [
'label' => '匯出',
],
],
],
'notifications' => [
'completed' => [
'title' => '匯出完成',
'actions' => [
'download_csv' => [
'label' => '下載 .csv 檔案',
],
'download_xlsx' => [
'label' => '下載 .xlsx 檔案',
],
],
],
'max_rows' => [
'title' => '匯出的檔案過大',
'body' => '你不能一次匯出超過 1 行紀錄。|你不能一次匯出超過 :count 行紀錄。',
],
'started' => [
'title' => '匯出開始',
'body' => '你的匯出已經開始,將在背景處理共 1 行。|你的匯出已經開始,將在背景處理共 :count 行。',
],
],
'file_name' => 'export-:export_id-:model',
];
@@ -0,0 +1,76 @@
<?php
return [
'label' => '匯入:label',
'modal' => [
'heading' => '匯入:label',
'form' => [
'file' => [
'label' => '檔案',
'placeholder' => '上傳一個 CSV 檔案',
],
'columns' => [
'label' => '欄位',
'placeholder' => '選擇一個欄位',
],
],
'actions' => [
'download_example' => [
'label' => '下載一個 CSV 模板',
],
'import' => [
'label' => '匯入',
],
],
],
'notifications' => [
'completed' => [
'title' => '匯入完成',
'actions' => [
'download_failed_rows_csv' => [
'label' => '下載匯入失敗的紀錄|下載匯入失敗的紀錄',
],
],
],
'max_rows' => [
'title' => '上傳的 CSV 檔案過大',
'body' => '你不能一次匯入超過 1 行紀錄。|你不能一次匯入超過 :count 行紀錄。',
],
'started' => [
'title' => '匯入開始',
'body' => '你的匯入已經開始,將在後台處理共 1 行。|你的匯入已經開始,將在後台處理共 :count 行。',
],
],
'example_csv' => [
'file_name' => ':importer-example',
],
'failure_csv' => [
'file_name' => 'import-:import_id-:csv_name-failed-rows',
'error_header' => '錯誤',
'system_error' => '系統錯誤,請聯繫官方。',
],
];
@@ -26,7 +26,11 @@
:wire:click="$action->getLivewireClickHandler()"
:wire:target="$action->getLivewireTarget()"
:x-on:click="$action->getAlpineClickHandler()"
:attributes="\Filament\Support\prepare_inherited_attributes($attributes)->merge($action->getExtraAttributes(), escape: false)"
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->merge($action->getExtraAttributes(), escape: false)
->class(['fi-ac-action'])
"
>
{{ $slot }}
</x-dynamic-component>
@@ -59,6 +59,10 @@ trait CanExportRecords
*/
protected array | Closure | null $formats = null;
protected ?Closure $modifyQueryUsing = null;
protected bool | Closure $hasColumnMapping = true;
protected function setUp(): void
{
parent::setUp();
@@ -71,8 +75,8 @@ trait CanExportRecords
$this->groupedIcon(FilamentIcon::resolve('actions::export-action.grouped') ?? 'heroicon-m-arrow-down-tray');
$this->form(fn (ExportAction | ExportTableAction | ExportTableBulkAction $action): array => array_merge([
Fieldset::make(__('filament-actions::export.modal.form.columns.label'))
$this->form(fn (ExportAction | ExportTableAction | ExportTableBulkAction $action): array => [
...($action->hasColumnMapping() ? [Fieldset::make(__('filament-actions::export.modal.form.columns.label'))
->columns(1)
->inlineLabel()
->schema(function () use ($action): array {
@@ -81,7 +85,7 @@ trait CanExportRecords
Forms\Components\Checkbox::make('isEnabled')
->label(__('filament-actions::export.modal.form.columns.form.is_enabled.label', ['column' => $column->getName()]))
->hiddenLabel()
->default(true)
->default($column->isEnabledByDefault())
->live()
->grow(false),
Forms\Components\TextInput::make('label')
@@ -97,8 +101,9 @@ trait CanExportRecords
$action->getExporter()::getColumns(),
);
})
->statePath('columnMap'),
], $action->getExporter()::getOptionsFormComponents()));
->statePath('columnMap')] : []),
...$action->getExporter()::getOptionsFormComponents(),
]);
$this->action(function (ExportAction | ExportTableAction | ExportTableBulkAction $action, array $data, Component $livewire) {
if ($livewire instanceof HasTable) {
@@ -107,6 +112,12 @@ trait CanExportRecords
$query = $action->getExporter()::getModel()::query();
}
if ($this->modifyQueryUsing) {
$query = $this->evaluate($this->modifyQueryUsing, [
'query' => $query,
]) ?? $query;
}
$records = $action instanceof ExportTableBulkAction ? $action->getRecords() : null;
$totalRows = $records ? $records->count() : $query->count();
@@ -118,7 +129,7 @@ trait CanExportRecords
->body(trans_choice('filament-actions::export.notifications.max_rows.body', $maxRows, [
'count' => format_number($maxRows),
]))
->success()
->danger()
->send();
return;
@@ -131,14 +142,20 @@ trait CanExportRecords
Arr::except($data, ['columnMap']),
);
$columnMap = collect($data['columnMap'])
->dot()
->reduce(fn (Collection $carry, mixed $value, string $key): Collection => $carry->mergeRecursive([
Str::beforeLast($key, '.') => [Str::afterLast($key, '.') => $value],
]), collect())
->filter(fn (array $column): bool => $column['isEnabled'] ?? false)
->mapWithKeys(fn (array $column, string $columnName): array => [$columnName => $column['label']])
->all();
if ($action->hasColumnMapping()) {
$columnMap = collect($data['columnMap'])
->dot()
->reduce(fn (Collection $carry, mixed $value, string $key): Collection => $carry->mergeRecursive([
Str::beforeLast($key, '.') => [Str::afterLast($key, '.') => $value],
]), collect())
->filter(fn (array $column): bool => $column['isEnabled'] ?? false)
->mapWithKeys(fn (array $column, string $columnName): array => [$columnName => $column['label']])
->all();
} else {
$columnMap = collect($action->getExporter()::getColumns())
->mapWithKeys(fn (ExportColumn $column): array => [$column->getName() => $column->getLabel()])
->all();
}
$export = app(Export::class);
$export->user()->associate($user);
@@ -166,6 +183,11 @@ trait CanExportRecords
$job = $action->getJob();
$jobQueue = $exporter->getJobQueue();
$jobConnection = $exporter->getJobConnection();
$jobBatchName = $exporter->getJobBatchName();
// We do not want to send the loaded user relationship to the queue in job payloads,
// in case it contains attributes that are not serializable, such as binary columns.
$export->unsetRelation('user');
$makeCreateXlsxFileJob = fn (): CreateXlsxFile => app(CreateXlsxFile::class, [
'export' => $export,
@@ -190,6 +212,10 @@ trait CanExportRecords
filled($jobConnection),
fn (PendingBatch $batch) => $batch->onConnection($jobConnection),
)
->when(
filled($jobBatchName),
fn (PendingBatch $batch) => $batch->name($jobBatchName),
)
->allowFailures(),
...(($hasXlsx && (! $hasCsv)) ? [$makeCreateXlsxFileJob()] : []),
app(ExportCompletion::class, [
@@ -363,4 +389,23 @@ trait CanExportRecords
{
return $this->evaluate($this->formats);
}
public function modifyQueryUsing(?Closure $callback): static
{
$this->modifyQueryUsing = $callback;
return $this;
}
public function columnMapping(bool | Closure $condition = true): static
{
$this->hasColumnMapping = $condition;
return $this;
}
public function hasColumnMapping(): bool
{
return (bool) $this->evaluate($this->hasColumnMapping);
}
}
@@ -183,7 +183,7 @@ trait CanImportRecords
->body(trans_choice('filament-actions::import.notifications.max_rows.body', $maxRows, [
'count' => format_number($maxRows),
]))
->success()
->danger()
->send();
return;
@@ -211,6 +211,10 @@ trait CanImportRecords
Arr::except($data, ['file', 'columnMap']),
);
// We do not want to send the loaded user relationship to the queue in job payloads,
// in case it contains attributes that are not serializable, such as binary columns.
$import->unsetRelation('user');
$importJobs = collect($importChunks)
->map(fn (array $importChunk): object => new ($job)(
$import,
@@ -234,6 +238,10 @@ trait CanImportRecords
filled($jobConnection = $importer->getJobConnection()),
fn (PendingBatch $batch) => $batch->onConnection($jobConnection),
)
->when(
filled($jobBatchName = $importer->getJobBatchName()),
fn (PendingBatch $batch) => $batch->name($jobBatchName),
)
->finally(function () use ($import) {
$import->touch('completed_at');
@@ -300,7 +308,7 @@ trait CanImportRecords
}
$csv->insertOne(array_map(
fn (ImportColumn $column): string => $column->getName(),
fn (ImportColumn $column): string => $column->getExampleHeader(),
$columns,
));
@@ -11,13 +11,18 @@ class CsvDownloader implements Downloader
public function __invoke(Export $export): StreamedResponse
{
$disk = $export->getFileDisk();
$directory = $export->getFileDirectory();
return response()->streamDownload(function () use ($disk, $export) {
echo $disk->get($export->getFileDirectory() . DIRECTORY_SEPARATOR . 'headers.csv');
if (! $disk->exists($directory)) {
abort(419);
}
return response()->streamDownload(function () use ($disk, $directory) {
echo $disk->get($directory . DIRECTORY_SEPARATOR . 'headers.csv');
flush();
foreach ($disk->files($export->getFileDirectory()) as $file) {
foreach ($disk->files($directory) as $file) {
if (str($file)->endsWith('headers.csv')) {
continue;
}
@@ -15,10 +15,15 @@ class XlsxDownloader implements Downloader
public function __invoke(Export $export): StreamedResponse
{
$disk = $export->getFileDisk();
$directory = $export->getFileDirectory();
if (! $disk->exists($directory)) {
abort(419);
}
$fileName = $export->file_name . '.xlsx';
if ($disk->exists($filePath = $export->getFileDirectory() . DIRECTORY_SEPARATOR . $fileName)) {
if ($disk->exists($filePath = $directory . DIRECTORY_SEPARATOR . $fileName)) {
return $disk->download($filePath);
}
@@ -36,12 +41,12 @@ class XlsxDownloader implements Downloader
}
};
return response()->streamDownload(function () use ($disk, $export, $fileName, $writer, $writeRowsFromFile) {
return response()->streamDownload(function () use ($disk, $directory, $fileName, $writer, $writeRowsFromFile) {
$writer->openToBrowser($fileName);
$writeRowsFromFile($export->getFileDirectory() . DIRECTORY_SEPARATOR . 'headers.csv');
$writeRowsFromFile($directory . DIRECTORY_SEPARATOR . 'headers.csv');
foreach ($disk->files($export->getFileDirectory()) as $file) {
foreach ($disk->files($directory) as $file) {
if (str($file)->endsWith('headers.csv')) {
continue;
}
+18 -2
View File
@@ -22,6 +22,10 @@ class ExportColumn extends Component
protected ?Exporter $exporter = null;
protected bool | Closure $isEnabledByDefault = true;
protected string $evaluationIdentifier = 'column';
final public function __construct(string $name)
{
$this->name($name);
@@ -56,6 +60,13 @@ class ExportColumn extends Component
return $this;
}
public function enabledByDefault(bool | Closure $condition): static
{
$this->isEnabledByDefault = $condition;
return $this;
}
public function getName(): string
{
return $this->name;
@@ -66,9 +77,14 @@ class ExportColumn extends Component
return $this->exporter;
}
public function isEnabledByDefault(): bool
{
return (bool) $this->evaluate($this->isEnabledByDefault);
}
public function getRecord(): ?Model
{
return $this->getExporter()->getRecord();
return $this->getExporter()?->getRecord();
}
public function getLabel(): ?string
@@ -106,7 +122,7 @@ class ExportColumn extends Component
public function applyEagerLoading(EloquentBuilder $query): EloquentBuilder
{
if (! $this->queriesRelationships($query->getModel())) {
if (! $this->hasRelationship($query->getModel())) {
return $query;
}
@@ -105,6 +105,11 @@ abstract class Exporter
return null;
}
public function getJobBatchName(): ?string
{
return null;
}
/**
* @return array<ExportColumn>
*/
@@ -5,13 +5,20 @@ namespace Filament\Actions\Exports\Http\Controllers;
use Filament\Actions\Exports\Enums\ExportFormat;
use Filament\Actions\Exports\Models\Export;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Symfony\Component\HttpFoundation\StreamedResponse;
use function Filament\authorize;
class DownloadExport
{
public function __invoke(Request $request, Export $export): StreamedResponse
{
abort_unless($export->user->is(auth()->user()), 403);
if (filled(Gate::getPolicyFor($export::class))) {
authorize('view', $export);
} else {
abort_unless($export->user()->is(auth()->user()), 403);
}
$format = ExportFormat::tryFrom($request->query('format'));
@@ -96,8 +96,19 @@ class ExportCsv implements ShouldQueue
$filePath = $this->export->getFileDirectory() . DIRECTORY_SEPARATOR . str_pad(strval($this->page), 16, '0', STR_PAD_LEFT) . '.csv';
$this->export->getFileDisk()->put($filePath, $csv->toString(), Filesystem::VISIBILITY_PRIVATE);
$this->export->increment('processed_rows', $processedRows);
$this->export->increment('successful_rows', $successfulRows);
$this->export->refresh();
$exportProcessedRows = $this->export->processed_rows + $processedRows;
$this->export->processed_rows = ($exportProcessedRows < $this->export->total_rows) ?
$exportProcessedRows :
$this->export->total_rows;
$exportSuccessfulRows = $this->export->successful_rows + $successfulRows;
$this->export->successful_rows = ($exportSuccessfulRows < $this->export->total_rows) ?
$exportSuccessfulRows :
$this->export->total_rows;
$this->export->save();
$this->handleExceptions($exceptions);
}
@@ -59,12 +59,17 @@ class PrepareCsvExport implements ShouldQueue
$query = EloquentSerializeFacade::unserialize($this->query);
$keyName = $query->getModel()->getKeyName();
$qualifiedKeyName = $query->getModel()->getQualifiedKeyName();
$exportCsvJob = $this->getExportCsvJob();
$totalRows = 0;
$page = 1;
// We do not want to send the loaded user relationship to the queue in job payloads,
// in case it contains attributes that are not serializable, such as binary columns.
$this->export->unsetRelation('user');
$dispatchRecords = function (array $records) use ($exportCsvJob, &$page, &$totalRows) {
$recordsCount = count($records);
@@ -103,18 +108,41 @@ class PrepareCsvExport implements ShouldQueue
return;
}
$baseQuery = $query->toBase();
$sortDirection = $baseQuery->orders[0]['direction'] ?? 'asc';
$chunkKeySize = $this->chunkSize * 10;
$baseQuery
->select([$query->getModel()->getQualifiedKeyName()])
->orderedChunkById(
$this->chunkSize * 10,
$baseQuery = $query->toBase();
$baseQuery->distinct($qualifiedKeyName);
/** @phpstan-ignore-next-line */
$baseQueryOrders = $baseQuery->orders ?? [];
$baseQueryOrdersCount = count($baseQueryOrders);
if (
(
($baseQueryOrdersCount === 1) &&
(! in_array($baseQueryOrders[0]['column'] ?? null, [$keyName, $qualifiedKeyName]))
) ||
($baseQueryOrdersCount > 1)
) {
$baseQuery->chunk(
$this->chunkSize,
fn (Collection $records) => $dispatchRecords(
Arr::pluck($records->all(), $keyName),
),
$keyName,
descending: $sortDirection === 'desc',
);
return;
}
$baseQuery
->select([$qualifiedKeyName])
->orderedChunkById(
$chunkKeySize,
fn (Collection $records) => $dispatchRecords(
Arr::pluck($records->all(), $keyName),
),
column: $keyName,
descending: ($baseQueryOrders[0]['direction'] ?? 'asc') === 'desc',
);
}
@@ -4,15 +4,22 @@ namespace Filament\Actions\Imports\Http\Controllers;
use Filament\Actions\Imports\Models\FailedImportRow;
use Filament\Actions\Imports\Models\Import;
use Illuminate\Support\Facades\Gate;
use League\Csv\Writer;
use SplTempFileObject;
use Symfony\Component\HttpFoundation\StreamedResponse;
use function Filament\authorize;
class DownloadImportFailureCsv
{
public function __invoke(Import $import): StreamedResponse
{
abort_unless($import->user->is(auth()->user()), 403);
if (filled(Gate::getPolicyFor($import::class))) {
authorize('view', $import);
} else {
abort_unless($import->user()->is(auth()->user()), 403);
}
$csv = Writer::createFromFileObject(new SplTempFileObject());
+24 -1
View File
@@ -52,6 +52,8 @@ class ImportColumn extends Component
protected mixed $example = null;
protected string | Closure | null $exampleHeader = null;
protected string | Closure | null $relationship = null;
/**
@@ -66,6 +68,8 @@ class ImportColumn extends Component
protected string | Closure | null $validationAttribute = null;
protected string $evaluationIdentifier = 'column';
final public function __construct(string $name)
{
$this->name($name);
@@ -108,6 +112,13 @@ class ImportColumn extends Component
return $this;
}
public function exampleHeader(string | Closure | null $header): static
{
$this->exampleHeader = $header;
return $this;
}
public function requiredMapping(bool | Closure $condition = true): static
{
$this->isMappingRequired = $condition;
@@ -194,9 +205,16 @@ class ImportColumn extends Component
public function getGuesses(): array
{
$guesses = $this->evaluate($this->guesses);
array_unshift($guesses, $this->getName());
if (filled($label = $this->getLabel())) {
array_unshift($guesses, $this->getLabel());
}
return array_reduce($guesses, function (array $carry, string $guess): array {
$carry[] = Str::lower($guess);
$guess = (string) str($guess)
->lower()
->replace('-', ' ')
@@ -279,6 +297,11 @@ class ImportColumn extends Component
return $this->name;
}
public function getExampleHeader(): string
{
return $this->evaluate($this->exampleHeader) ?? $this->getName();
}
/**
* @return array<mixed>
*/
@@ -432,7 +455,7 @@ class ImportColumn extends Component
public function getRecord(): ?Model
{
return $this->getImporter()->getRecord();
return $this->getImporter()?->getRecord();
}
public function isMappingRequired(): bool
+26 -2
View File
@@ -80,7 +80,12 @@ abstract class Importer
foreach ($this->getCachedColumns() as $column) {
$columnName = $column->getName();
$rowColumnName = $this->columnMap[$columnName] ?? null;
if (blank($this->columnMap[$columnName] ?? null)) {
continue;
}
$rowColumnName = $this->columnMap[$columnName];
if (! array_key_exists($rowColumnName, $this->data)) {
continue;
@@ -141,6 +146,10 @@ abstract class Importer
foreach ($this->getCachedColumns() as $column) {
$columnName = $column->getName();
if (blank($this->columnMap[$columnName] ?? null)) {
continue;
}
$rules[$columnName] = $column->getDataValidationRules();
if (
@@ -170,13 +179,19 @@ abstract class Importer
$attributes = [];
foreach ($this->getCachedColumns() as $column) {
$columnName = $column->getName();
if (blank($this->columnMap[$columnName] ?? null)) {
continue;
}
$validationAttribute = $column->getValidationAttribute();
if (blank($validationAttribute)) {
continue;
}
$attributes[$column->getName()] = $validationAttribute;
$attributes[$columnName] = $validationAttribute;
}
return $attributes;
@@ -187,6 +202,10 @@ abstract class Importer
foreach ($this->getCachedColumns() as $column) {
$columnName = $column->getName();
if (blank($this->columnMap[$columnName] ?? null)) {
continue;
}
if (! array_key_exists($columnName, $this->data)) {
continue;
}
@@ -264,6 +283,11 @@ abstract class Importer
return null;
}
public function getJobBatchName(): ?string
{
return null;
}
/**
* @return array<ImportColumn>
*/
@@ -73,6 +73,8 @@ class ImportCsv implements ShouldQueue
}
foreach (($rows ?? $this->rows) as $row) {
$row = $this->utf8Encode($row);
try {
DB::transaction(fn () => ($this->importer)($row));
$successfulRows++;
@@ -87,8 +89,19 @@ class ImportCsv implements ShouldQueue
$processedRows++;
}
$this->import->increment('processed_rows', $processedRows);
$this->import->increment('successful_rows', $successfulRows);
$this->import->refresh();
$importProcessedRows = $this->import->processed_rows + $processedRows;
$this->import->processed_rows = ($importProcessedRows < $this->import->total_rows) ?
$importProcessedRows :
$this->import->total_rows;
$importSuccessfulRows = $this->import->successful_rows + $successfulRows;
$this->import->successful_rows = ($importSuccessfulRows < $this->import->total_rows) ?
$importSuccessfulRows :
$this->import->total_rows;
$this->import->save();
$this->handleExceptions($exceptions);
}
@@ -118,6 +131,19 @@ class ImportCsv implements ShouldQueue
$failedRow->save();
}
protected function utf8Encode(mixed $value): mixed
{
if (is_array($value)) {
return array_map($this->utf8Encode(...), $value);
}
if (is_string($value)) {
return mb_convert_encoding($value, 'UTF-8', 'UTF-8');
}
return $value;
}
/**
* @param array<Throwable> $exceptions
*/
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+14 -1
View File
@@ -204,6 +204,19 @@ Select::make('author_id')
->preload()
```
### Excluding the current record
When working with recursive relationships, you will likely want to remove the current record from the set of results.
This can be easily be done using the `ignoreRecord` argument:
```php
use Filament\Forms\Components\Select;
Select::make('parent_id')
->relationship(name: 'parent', titleAttribute: 'name', ignoreRecord: true)
```
### Customizing the relationship query
You may customize the database query that retrieves options using the third parameter of the `relationship()` method:
@@ -354,7 +367,7 @@ MorphToSelect::make('commentable')
])
```
> Many of the same options in the select field are available for `MorphToSelect`, including `searchable()`, `preload()`, `allowHtml()`, and `optionsLimit()`.
> Many of the same options in the select field are available for `MorphToSelect`, including `searchable()`, `preload()`, `native()`, `allowHtml()`, and `optionsLimit()`.
## Allowing HTML in the option labels
@@ -346,6 +346,8 @@ FileUpload::make('attachment')
When the form is submitted, a temporary file upload object will be returned instead of a permanently stored file path. This is perfect for temporary files like imported CSVs.
Please be aware that images, video and audio files will not show the stored file name in the form's preview, unless you use [`previewable(false)`](#previewing-files). This is due to a limitation with the FilePond preview plugin.
## Orienting images from their EXIF data
By default, FilePond will automatically orient images based on their EXIF data. If you wish to disable this behaviour, you can use the `orientImagesFromExif(false)` method:
@@ -379,6 +381,17 @@ FileUpload::make('attachment')
->fetchFileInformation(false)
```
## Customizing the uploading message
You may customize the uploading message that is displayed in the form's submit button using the `uploadingMessage()` method:
```php
use Filament\Forms\Components\FileUpload;
FileUpload::make('attachment')
->uploadingMessage('Uploading attachment...')
```
## File upload validation
As well as all rules listed on the [validation](../validation) page, there are additional rules that are specific to file uploads.
+3 -3
View File
@@ -234,7 +234,7 @@ Repeater::make('qualifications')
### Reordering items in a relationship
By default, [reordering](#reordering-items) relationship repeater items is disabled. This is because your related model needs an `sort` column to store the order of related records. To enable reordering, you may use the `orderColumn()` method, passing in a name of the column on your related model to store the order in:
By default, [reordering](#reordering-items) relationship repeater items is disabled. This is because your related model needs a `sort` column to store the order of related records. To enable reordering, you may use the `orderColumn()` method, passing in a name of the column on your related model to store the order in:
```php
use Filament\Forms\Components\Repeater;
@@ -287,7 +287,7 @@ class OrderProduct extends Pivot
{
return $this->belongsTo(Order::class);
}
public function product(): BelongsTo
{
return $this->belongsTo(Product::class);
@@ -634,7 +634,7 @@ Repeater::make('members')
->icon('heroicon-m-envelope')
->action(function (array $arguments, Repeater $component): void {
$itemData = $component->getItemState($arguments['item']);
Mail::to($itemData['email'])
->send(
// ...
@@ -165,6 +165,27 @@ Wizard\Step::make('Order')
]),
```
### Preventing the next step from being loaded
Inside `afterValidation()` or `beforeValidation()`, you may throw `Filament\Support\Exceptions\Halt`, which will prevent the wizard from loading the next step:
```php
use Filament\Forms\Components\Wizard;
use Filament\Support\Exceptions\Halt;
Wizard\Step::make('Order')
->afterValidation(function () {
// ...
if (true) {
throw new Halt();
}
})
->schema([
// ...
]),
```
## Using grid columns within a step
You may use the `columns()` method to customize the [grid](grid) within the step:
+1 -1
View File
@@ -589,7 +589,7 @@ In this example, the customer's name is not `required()`, and the email address
## Inserting Livewire components into a form
You may use insert a Livewire component directly into a form:
You may insert a Livewire component directly into a form:
```php
use Filament\Forms\Components\Livewire;
@@ -15,7 +15,7 @@
}
.fi-fo-rich-editor trix-toolbar .trix-dialog__link-fields .trix-input {
@apply block w-full rounded-md border-none bg-white py-1.5 pe-3 ps-3 text-sm text-gray-950 outline-none ring-1 ring-gray-950/10 transition duration-75 placeholder:text-gray-400 focus-within:ring-primary-600 sm:text-sm sm:leading-6 dark:bg-gray-700 dark:text-white dark:ring-white/20 dark:placeholder:text-gray-500 dark:focus-within:ring-primary-600;
@apply block w-full rounded-md border-none bg-white py-1.5 pe-3 ps-3 text-sm text-gray-950 outline-none ring-1 ring-gray-950/10 transition duration-75 placeholder:text-gray-400 focus-within:ring-primary-600 dark:bg-gray-700 dark:text-white dark:ring-white/20 dark:placeholder:text-gray-500 dark:focus-within:ring-primary-600 sm:text-sm sm:leading-6;
}
.fi-fo-rich-editor
@@ -147,7 +147,7 @@ select:not(.choices) {
/* !important is used to override default Tailwind input styling */
.choices__input {
@apply border-none !bg-transparent !p-0 !text-base text-gray-950 transition duration-75 placeholder:text-gray-400 focus-visible:!ring-0 disabled:text-gray-500 disabled:[-webkit-text-fill-color:theme(colors.gray[500])] sm:!text-sm sm:leading-6 dark:text-white dark:placeholder:text-gray-500 dark:disabled:text-gray-400 dark:disabled:[-webkit-text-fill-color:theme(colors.gray[400])];
@apply border-none !bg-transparent !p-0 !text-base text-gray-950 transition duration-75 placeholder:text-gray-400 focus-visible:!ring-0 disabled:text-gray-500 disabled:[-webkit-text-fill-color:theme(colors.gray[500])] dark:text-white dark:placeholder:text-gray-500 dark:disabled:text-gray-400 dark:disabled:[-webkit-text-fill-color:theme(colors.gray[400])] sm:!text-sm sm:leading-6;
}
.choices__list--dropdown .choices__input {
@@ -50,8 +50,10 @@ export default function fileUploadFormComponent({
isOpenable,
isPreviewable,
isReorderable,
itemPanelAspectRatio,
loadingIndicatorPosition,
locale,
maxFiles,
maxSize,
minSize,
panelAspectRatio,
@@ -65,6 +67,7 @@ export default function fileUploadFormComponent({
shouldTransformImage,
state,
uploadButtonPosition,
uploadingMessage,
uploadProgressIndicatorPosition,
uploadUsing,
}) {
@@ -112,10 +115,12 @@ export default function fileUploadFormComponent({
imageResizeUpscale,
itemInsertLocation: shouldAppendFiles ? 'after' : 'before',
...(placeholder && { labelIdle: placeholder }),
maxFiles,
maxFileSize: maxSize,
minFileSize: minSize,
styleButtonProcessItemPosition: uploadButtonPosition,
styleButtonRemoveItemPosition: removeUploadedFileButtonPosition,
styleItemPanelAspectRatio: itemPanelAspectRatio,
styleLoadIndicatorPosition: loadingIndicatorPosition,
stylePanelAspectRatio: panelAspectRatio,
stylePanelLayout: panelLayout,
@@ -271,7 +276,9 @@ export default function fileUploadFormComponent({
return
}
this.dispatchFormEvent('file-upload-started')
this.dispatchFormEvent('form-processing-started', {
message: uploadingMessage,
})
})
const handleFileProcessing = async () => {
@@ -289,7 +296,7 @@ export default function fileUploadFormComponent({
return
}
this.dispatchFormEvent('file-upload-finished')
this.dispatchFormEvent('form-processing-finished')
}
this.pond.on('processfile', handleFileProcessing)
@@ -306,11 +313,12 @@ export default function fileUploadFormComponent({
this.pond = null
},
dispatchFormEvent: function (name) {
dispatchFormEvent: function (name, detail = {}) {
this.$el.closest('form')?.dispatchEvent(
new CustomEvent(name, {
composed: true,
cancelable: true,
detail,
}),
)
},
@@ -344,7 +352,10 @@ export default function fileUploadFormComponent({
options: {
type: 'local',
...(!uploadedFile.type ||
/^image/.test(uploadedFile.type)
(isPreviewable &&
(/^audio/.test(uploadedFile.type) ||
/^image/.test(uploadedFile.type) ||
/^video/.test(uploadedFile.type)))
? {}
: {
file: {
@@ -204,11 +204,7 @@ export default function markdownEditorFormComponent({
return
}
this.editor.value(this.state ?? '')
// There is an issue with the editor not rendering the content
// until after it is focused. All solutions online have been
// attempted and none have worked so far.
Alpine.raw(this.editor).value(this.state ?? '')
})
},
@@ -419,6 +419,31 @@ return [
'placeholder' => 'كلمة مفتاحية جديدة',
],
'text_input' => [
'actions' => [
'hide_password' => [
'label' => 'إخفاء كلمة المرور',
],
'show_password' => [
'label' => 'عرض كلمة المرور',
],
],
],
'toggle_buttons' => [
'boolean' => [
'true' => 'نعم',
'false' => 'لا',
],
],
'wizard' => [
'actions' => [
@@ -81,11 +81,11 @@ return [
],
'drag_crop' => [
'label' => `Mode d'arrossegament "retallar"`,
'label' => 'Mode d\'arrossegament "retallar"',
],
'drag_move' => [
'label' => `Mode d'arrossegament "moure"`,
'label' => 'Mode d\'arrossegament "moure"',
],
'flip_horizontal' => [
@@ -70,6 +70,134 @@ return [
],
'file_upload' => [
'editor' => [
'actions' => [
'cancel' => [
'label' => 'Abbrechen',
],
'drag_crop' => [
'label' => 'Drag Modus "beschneiden"',
],
'drag_move' => [
'label' => 'Drag Modus "verschieben"',
],
'flip_horizontal' => [
'label' => 'Bild horizontal spiegeln',
],
'flip_vertical' => [
'label' => 'Bild vertikal spiegeln',
],
'move_down' => [
'label' => 'Bild nach unten',
],
'move_left' => [
'label' => 'Bild nach links',
],
'move_right' => [
'label' => 'Bild nach rechts',
],
'move_up' => [
'label' => 'Bild nach oben',
],
'reset' => [
'label' => 'Zurücksetzen',
],
'rotate_left' => [
'label' => 'Bild nach links kippen',
],
'rotate_right' => [
'label' => 'Bild nach rechts kippen',
],
'set_aspect_ratio' => [
'label' => 'Seitenverhältnis festlegen :ratio',
],
'save' => [
'label' => 'Speichern',
],
'zoom_100' => [
'label' => 'Bild Zoom 100%',
],
'zoom_in' => [
'label' => 'Hereinzoomen',
],
'zoom_out' => [
'label' => 'Herauszoomen',
],
],
'fields' => [
'height' => [
'label' => 'Höhe',
'unit' => 'px',
],
'rotation' => [
'label' => 'Drehung',
'unit' => 'deg',
],
'width' => [
'label' => 'Breite',
'unit' => 'px',
],
'x_position' => [
'label' => 'X',
'unit' => 'px',
],
'y_position' => [
'label' => 'Y',
'unit' => 'px',
],
],
'aspect_ratios' => [
'label' => 'Seitenverhältnisse',
'no_fixed' => [
'label' => 'Frei',
],
],
'svg' => [
'messages' => [
'confirmation' => 'Das Bearbeiten von SVG Dateien ist nicht empfohlen, da es Qualitätsverluste beim Verändern der Größe geben kann.\n Wirklich fortfahren?',
'disabled' => 'Das Bearbeiten von SVG Dateien ist deaktiviert, da es Qualitätsverluste beim Verändern der Größe geben kann.',
],
],
],
],
'key_value' => [
'actions' => [
@@ -0,0 +1,10 @@
<?php
return [
'distinct' => [
'must_be_selected' => 'Wenigstens muss das :attribute ausgewählt sein.',
'only_one_must_be_selected' => 'Nur das :attribute Feld darf ausgewählt sein.',
],
];
@@ -185,6 +185,15 @@ return [
],
'svg' => [
'messages' => [
'confirmation' => 'ویرایش فایل‌های SVG توصیه نمی‌شود، زیرا می‌تواند منجر به کاهش کیفیت در هنگام مقیاس‌بندی شود.\n آیا مطمئن هستید که می‌خواهید ادامه دهید؟',
'disabled' => 'ویرایش فایل‌های SVG غیرفعال است زیرا می‌تواند منجر به کاهش کیفیت در هنگام مقیاس‌بندی شود.',
],
],
],
],
@@ -241,6 +250,15 @@ return [
],
'radio' => [
'boolean' => [
'true' => 'بله',
'false' => 'خیر',
],
],
'repeater' => [
'actions' => [
@@ -249,6 +267,10 @@ return [
'label' => 'افزودن به :label',
],
'add_between' => [
'label' => 'درج بین',
],
'delete' => [
'label' => 'حذف',
],
@@ -397,6 +419,31 @@ return [
'placeholder' => 'تگ جدید',
],
'text_input' => [
'actions' => [
'hide_password' => [
'label' => 'مخفی کردن رمز',
],
'show_password' => [
'label' => 'نشان دادن رمز',
],
],
],
'toggle_buttons' => [
'boolean' => [
'true' => 'بله',
'false' => 'خیر',
],
],
'wizard' => [
'actions' => [
@@ -183,13 +183,13 @@ return [
'label' => 'Libre',
],
'svg' => [
],
'messages' => [
'confirmation' => 'La modification des fichiers SVG n\'est pas recommandée car elle peut entraîner une perte de qualité lors de la mise à l\'échelle.\n Êtes-vous sûr de vouloir continuer ?',
'disabled' => 'La modification des fichiers SVG est désactivée car elle peut entraîner une perte de qualité lors de la mise à l\'échelle.',
],
'svg' => [
'messages' => [
'confirmation' => 'La modification des fichiers SVG n\'est pas recommandée car elle peut entraîner une perte de qualité lors de la mise à l\'échelle.\n Êtes-vous sûr de vouloir continuer ?',
'disabled' => 'La modification des fichiers SVG est désactivée car elle peut entraîner une perte de qualité lors de la mise à l\'échelle.',
],
],
@@ -419,6 +419,31 @@ return [
'placeholder' => 'Nouveau tag',
],
'text_input' => [
'actions' => [
'hide_password' => [
'label' => 'Masquer le mot de passe',
],
'show_password' => [
'label' => 'Montrer le mot de passe',
],
],
],
'toggle_buttons' => [
'boolean' => [
'true' => 'Oui',
'false' => 'Non',
],
],
'wizard' => [
'actions' => [
@@ -419,6 +419,31 @@ return [
'placeholder' => 'Címke hozzáadása',
],
'text_input' => [
'actions' => [
'hide_password' => [
'label' => 'Jelszó elrejtése',
],
'show_password' => [
'label' => 'Jelszó megjelenítése',
],
],
],
'toggle_buttons' => [
'boolean' => [
'true' => 'Igen',
'false' => 'Nem',
],
],
'wizard' => [
'actions' => [
@@ -93,7 +93,7 @@ return [
],
'flip_vertical' => [
'label' => 'Balik gambar vertical',
'label' => 'Balik gambar secara vertikal',
],
'move_down' => [
@@ -424,11 +424,11 @@ return [
'actions' => [
'hide_password' => [
'label' => 'Sembunyikan password',
'label' => 'Sembunyikan kata sandi',
],
'show_password' => [
'label' => 'Tampilkan password',
'label' => 'Tampilkan kata sandi',
],
],
+17 -17
View File
@@ -6,39 +6,39 @@ return [
'actions' => [
'clone_item' => [
'clone' => [
'label' => 'Хуулбарлах',
],
'create_item' => [
'add' => [
'label' => 'Нэмэх :label',
],
'create_item_between' => [
'add_between' => [
'label' => 'Оруулах',
],
'delete_item' => [
'delete' => [
'label' => 'Устгах',
],
'move_item' => [
'reorder' => [
'label' => 'Зөөх',
],
'move_item_down' => [
'move_down' => [
'label' => 'Доош зөөх',
],
'move_item_up' => [
'move_up' => [
'label' => 'Дээш зөөх',
],
'collapse_item' => [
'collapse' => [
'label' => 'Хаах',
],
'expand_item' => [
'expand' => [
'label' => 'Нээх',
],
@@ -123,35 +123,35 @@ return [
'actions' => [
'create_item' => [
'add' => [
'label' => 'Нэмэх :label',
],
'delete_item' => [
'delete' => [
'label' => 'Устгах',
],
'clone_item' => [
'clone' => [
'label' => 'Хуулбарлах',
],
'move_item' => [
'reorder' => [
'label' => 'Зөөх',
],
'move_item_down' => [
'move_down' => [
'label' => 'Доош зөөх',
],
'move_item_up' => [
'move_up' => [
'label' => 'Дээш зөөх',
],
'collapse_item' => [
'collapse' => [
'label' => 'Хаах',
],
'expand_item' => [
'expand' => [
'label' => 'Нээх',
],

Some files were not shown because too many files have changed in this diff Show More