├── .babelrc ├── .eslintrc.json ├── CHANGELOG.md ├── LICENSE ├── composer.json ├── config └── platform.php ├── database ├── factories │ ├── AttachmentFactory.php │ ├── RoleFactory.php │ └── UserFactory.php ├── migrations │ ├── 2015_04_12_000000_create_orchid_users_table.php │ ├── 2015_10_19_214424_create_orchid_roles_table.php │ ├── 2015_10_19_214425_create_orchid_role_users_table.php │ ├── 2016_08_07_125128_create_orchid_attachmentstable_table.php │ └── 2017_09_17_125801_create_notifications_table.php └── seeders │ ├── AttachmentsTableSeeder.php │ ├── OrchidDatabaseSeeder.php │ ├── RolesTableSeeder.php │ └── UsersTableSeeder.php ├── package.json ├── phpunit.xml ├── pint.json ├── psalm.xml ├── public ├── assets │ ├── app.css │ ├── app.js │ └── app.rtl.css ├── favicon.svg └── manifest.json ├── readme.md ├── resources ├── js │ ├── app.js │ ├── controllers │ │ ├── application_controller.js │ │ ├── attach_controller.js │ │ ├── browsing_controller.js │ │ ├── button_controller.js │ │ ├── chart_controller.js │ │ ├── checkbox_controller.js │ │ ├── code_controller.js │ │ ├── confirm_controller.js │ │ ├── cropper_controller.js │ │ ├── datetime_controller.js │ │ ├── filter_controller.js │ │ ├── form_controller.js │ │ ├── html_load_controller.js │ │ ├── input_controller.js │ │ ├── listener_controller.js │ │ ├── map_controller.js │ │ ├── matrix_controller.js │ │ ├── menu_controller.js │ │ ├── modal_controller.js │ │ ├── modal_toggle_controller.js │ │ ├── notification_controller.js │ │ ├── password_controller.js │ │ ├── picture_controller.js │ │ ├── popover_controller.js │ │ ├── pull-to-refresh_controller.js │ │ ├── quill_controller.js │ │ ├── radiobutton_controller.js │ │ ├── relation_controller.js │ │ ├── reload_controller.js │ │ ├── search_controller.js │ │ ├── select_controller.js │ │ ├── simplemde_controller.js │ │ ├── sortable_controller.js │ │ ├── table_controller.js │ │ ├── tabs_controller.js │ │ ├── toast_controller.js │ │ ├── toggle_controller.js │ │ ├── tooltip_controller.js │ │ ├── upload_controller.js │ │ ├── utm_controller.js │ │ └── viewport-entrance-toggle_controller.js │ └── orchid.js ├── lang │ ├── ar.json │ ├── ca.json │ ├── ckb.json │ ├── da.json │ ├── de.json │ ├── es.json │ ├── fa.json │ ├── fr.json │ ├── he.json │ ├── hu.json │ ├── id.json │ ├── it.json │ ├── ja.json │ ├── kk.json │ ├── kz.json │ ├── nl.json │ ├── pl.json │ ├── pt.json │ ├── pt_BR.json │ ├── ro.json │ ├── ru.json │ ├── tk.json │ ├── tr.json │ ├── uk.json │ ├── zh_CN.json │ └── zh_TW.json ├── sass │ ├── app.scss │ ├── core │ │ ├── buttons.scss │ │ ├── form.scss │ │ ├── layout.scss │ │ ├── mixins.scss │ │ ├── modals.scss │ │ ├── reset.scss │ │ ├── tables.scss │ │ └── utilities.scss │ ├── plugins │ │ ├── accordion.scss │ │ ├── attach.scss │ │ ├── dropzone.scss │ │ ├── load-opacity.scss │ │ ├── plugin.scss │ │ └── tom-select.scss │ └── theme │ │ └── variables.scss └── views │ ├── actions │ ├── button.blade.php │ ├── dropdown.blade.php │ ├── link.blade.php │ ├── menu.blade.php │ ├── modal.blade.php │ └── toggle.blade.php │ ├── app.blade.php │ ├── auth.blade.php │ ├── auth │ ├── impersonation.blade.php │ ├── lockme.blade.php │ ├── login.blade.php │ └── signin.blade.php │ ├── components │ ├── notification.blade.php │ ├── popover.blade.php │ └── stream.blade.php │ ├── dashboard.blade.php │ ├── dummy │ └── block.blade.php │ ├── errors │ └── 404.blade.php │ ├── fields │ ├── attach.blade.php │ ├── checkbox.blade.php │ ├── code.blade.php │ ├── cropper.blade.php │ ├── dataRange.blade.php │ ├── datetime.blade.php │ ├── group.blade.php │ ├── input.blade.php │ ├── label.blade.php │ ├── map.blade.php │ ├── matrix.blade.php │ ├── numberRange.blade.php │ ├── password.blade.php │ ├── picture.blade.php │ ├── quill.blade.php │ ├── radio.blade.php │ ├── radiobutton.blade.php │ ├── range.blade.php │ ├── relation.blade.php │ ├── select.blade.php │ ├── simplemde.blade.php │ ├── switch.blade.php │ ├── textarea.blade.php │ ├── upload.blade.php │ └── utm.blade.php │ ├── footer.blade.php │ ├── header.blade.php │ ├── layouts │ ├── accordion.blade.php │ ├── base.blade.php │ ├── blank.blade.php │ ├── block.blade.php │ ├── browsing.blade.php │ ├── card.blade.php │ ├── chart.blade.php │ ├── columns.blade.php │ ├── facepile.blade.php │ ├── filter.blade.php │ ├── legend.blade.php │ ├── listener.blade.php │ ├── metric.blade.php │ ├── modal.blade.php │ ├── pagination.blade.php │ ├── persona.blade.php │ ├── row.blade.php │ ├── selection.blade.php │ ├── sortable.blade.php │ ├── split.blade.php │ ├── tabMenu.blade.php │ ├── table.blade.php │ └── tabs.blade.php │ ├── partials │ ├── alert.blade.php │ ├── confirm.blade.php │ ├── fields │ │ ├── clear.blade.php │ │ ├── horizontal.blade.php │ │ ├── matrixRow.blade.php │ │ └── vertical.blade.php │ ├── layouts │ │ ├── dt.blade.php │ │ ├── filter.blade.php │ │ ├── selectedTd.blade.php │ │ ├── td.blade.php │ │ └── th.blade.php │ ├── notification-wrap.blade.php │ ├── notification.blade.php │ ├── pagination.blade.php │ ├── profile.blade.php │ ├── result-compact.blade.php │ ├── result.blade.php │ ├── search-modal.blade.php │ ├── search.blade.php │ ├── state.blade.php │ ├── toast.blade.php │ ├── update-assets.blade.php │ └── welcome.blade.php │ └── workspace │ ├── compact.blade.php │ └── full.blade.php ├── routes ├── auth.php └── dashboard.php ├── src ├── Access │ ├── Impersonation.php │ ├── RoleAccess.php │ ├── RoleInterface.php │ ├── StatusAccess.php │ ├── UserAccess.php │ ├── UserInterface.php │ └── UserSwitch.php ├── Alert │ ├── Alert.php │ └── Toast.php ├── Attachment │ ├── Attachable.php │ ├── Contracts │ │ └── Engine.php │ ├── Engines │ │ └── Generator.php │ ├── File.php │ ├── MimeTypes.php │ └── Models │ │ ├── Attachment.php │ │ └── Attachmentable.php ├── Filters │ ├── BaseHttpEloquentFilter.php │ ├── Filter.php │ ├── Filterable.php │ ├── HttpFilter.php │ └── Types │ │ ├── Ilike.php │ │ ├── Like.php │ │ ├── Where.php │ │ ├── WhereBetween.php │ │ ├── WhereDate.php │ │ ├── WhereDateStartEnd.php │ │ ├── WhereIn.php │ │ └── WhereMaxMin.php ├── Metrics │ ├── Chartable.php │ ├── GroupCollection.php │ └── TimeCollection.php ├── Platform │ ├── Commands │ │ ├── AdminCommand.php │ │ ├── ChartCommand.php │ │ ├── FieldCommand.php │ │ ├── FilterCommand.php │ │ ├── GeneratorCommand.php │ │ ├── InstallCommand.php │ │ ├── ListenerCommand.php │ │ ├── PresenterCommand.php │ │ ├── PublishCommand.php │ │ ├── RowsCommand.php │ │ ├── ScreenCommand.php │ │ ├── SelectionCommand.php │ │ ├── StubPublishCommand.php │ │ ├── TabMenuCommand.php │ │ └── TableCommand.php │ ├── Components │ │ ├── Notification.php │ │ └── Stream.php │ ├── Concerns │ │ └── Sortable.php │ ├── Configuration │ │ ├── ManagesMenu.php │ │ ├── ManagesModelOptions.php │ │ ├── ManagesPackage.php │ │ ├── ManagesPermissions.php │ │ ├── ManagesResources.php │ │ ├── ManagesScreens.php │ │ └── ManagesSearch.php │ ├── Dashboard.php │ ├── Events │ │ ├── AddRoleEvent.php │ │ ├── InstallEvent.php │ │ ├── RemoveRoleEvent.php │ │ ├── ReplicateFileEvent.php │ │ ├── UploadFileEvent.php │ │ └── UploadedFileEvent.php │ ├── Http │ │ ├── Controllers │ │ │ ├── AsyncController.php │ │ │ ├── AttachmentController.php │ │ │ ├── Controller.php │ │ │ ├── IndexController.php │ │ │ ├── LoginController.php │ │ │ ├── RelationController.php │ │ │ └── SortableController.php │ │ ├── Layouts │ │ │ ├── NotificationTable.php │ │ │ └── SearchLayout.php │ │ ├── Middleware │ │ │ ├── Access.php │ │ │ ├── BladeIcons.php │ │ │ └── Turbo.php │ │ ├── Requests │ │ │ └── RelationRequest.php │ │ └── Screens │ │ │ ├── NotificationScreen.php │ │ │ └── SearchScreen.php │ ├── ItemPermission.php │ ├── Models │ │ ├── Role.php │ │ └── User.php │ ├── Notifications │ │ ├── DashboardChannel.php │ │ └── DashboardMessage.php │ ├── OrchidServiceProvider.php │ └── Providers │ │ ├── ConsoleServiceProvider.php │ │ ├── FoundationServiceProvider.php │ │ ├── PlatformServiceProvider.php │ │ └── RouteServiceProvider.php ├── Screen │ ├── Action.php │ ├── Actions │ │ ├── Button.php │ │ ├── DropDown.php │ │ ├── Link.php │ │ ├── Menu.php │ │ ├── ModalToggle.php │ │ └── Toggle.php │ ├── AsMultiSource.php │ ├── AsSource.php │ ├── Builder.php │ ├── CanSee.php │ ├── Cell.php │ ├── Commander.php │ ├── Components │ │ ├── Cells │ │ │ ├── Boolean.php │ │ │ ├── Currency.php │ │ │ ├── DateTime.php │ │ │ ├── DateTimeSplit.php │ │ │ ├── Number.php │ │ │ ├── Percentage.php │ │ │ ├── Text.php │ │ │ └── Time.php │ │ └── Popover.php │ ├── Concerns │ │ ├── ComplexFieldConcern.php │ │ ├── HasFillablePublicProperties.php │ │ ├── HasTranslations.php │ │ ├── InteractsWithEncryptedState.php │ │ ├── Makeable.php │ │ ├── ModelStateRetrievable.php │ │ └── Multipliable.php │ ├── Contracts │ │ ├── Actionable.php │ │ ├── Cardable.php │ │ ├── Fieldable.php │ │ ├── Groupable.php │ │ ├── Personable.php │ │ └── Searchable.php │ ├── Exceptions │ │ └── FieldRequiredAttributeException.php │ ├── Field.php │ ├── Fields │ │ ├── Attach.php │ │ ├── CheckBox.php │ │ ├── Code.php │ │ ├── Cropper.php │ │ ├── DateRange.php │ │ ├── DateTimer.php │ │ ├── Group.php │ │ ├── Input.php │ │ ├── Label.php │ │ ├── Map.php │ │ ├── Matrix.php │ │ ├── NumberRange.php │ │ ├── Password.php │ │ ├── Picture.php │ │ ├── Quill.php │ │ ├── Radio.php │ │ ├── RadioButtons.php │ │ ├── Range.php │ │ ├── Relation.php │ │ ├── Select.php │ │ ├── SimpleMDE.php │ │ ├── Switcher.php │ │ ├── TextArea.php │ │ ├── TimeZone.php │ │ ├── UTM.php │ │ ├── Upload.php │ │ └── ViewField.php │ ├── Layout.php │ ├── LayoutFactory.php │ ├── Layouts │ │ ├── Accordion.php │ │ ├── Blank.php │ │ ├── Block.php │ │ ├── Browsing.php │ │ ├── Card.php │ │ ├── Chart.php │ │ ├── Columns.php │ │ ├── Component.php │ │ ├── Content.php │ │ ├── Facepile.php │ │ ├── Legend.php │ │ ├── Listener.php │ │ ├── Metric.php │ │ ├── Modal.php │ │ ├── Persona.php │ │ ├── Rows.php │ │ ├── Selection.php │ │ ├── Sortable.php │ │ ├── Split.php │ │ ├── TabMenu.php │ │ ├── Table.php │ │ ├── Tabs.php │ │ ├── View.php │ │ └── Wrapper.php │ ├── Repository.php │ ├── Screen.php │ ├── Sight.php │ └── TD.php └── Support │ ├── Assert.php │ ├── Attributes │ └── FlushOctaneState.php │ ├── Blade.php │ ├── BootstrapIconsPath.php │ ├── Color.php │ ├── Facades │ ├── Alert.php │ ├── Dashboard.php │ ├── Layout.php │ └── Toast.php │ ├── Formats.php │ ├── Init.php │ ├── Locale.php │ ├── Names.php │ ├── Presenter.php │ ├── Testing │ ├── DynamicTestScreen.php │ ├── MakesHttpRequestsWrapper.php │ └── ScreenTesting.php │ └── helpers.php ├── stubs ├── app │ ├── Orchid │ │ ├── Filters │ │ │ └── RoleFilter.php │ │ ├── Layouts │ │ │ ├── Examples │ │ │ │ ├── ChartBarExample.php │ │ │ │ ├── ChartLineExample.php │ │ │ │ ├── ChartPercentageExample.php │ │ │ │ ├── ChartPieExample.php │ │ │ │ ├── ExampleElements.php │ │ │ │ └── TabMenuExample.php │ │ │ ├── Role │ │ │ │ ├── RoleEditLayout.php │ │ │ │ ├── RoleListLayout.php │ │ │ │ └── RolePermissionLayout.php │ │ │ └── User │ │ │ │ ├── ProfilePasswordLayout.php │ │ │ │ ├── UserEditLayout.php │ │ │ │ ├── UserFiltersLayout.php │ │ │ │ ├── UserListLayout.php │ │ │ │ ├── UserPasswordLayout.php │ │ │ │ └── UserRoleLayout.php │ │ ├── PlatformProvider.php │ │ ├── Presenters │ │ │ └── UserPresenter.php │ │ └── Screens │ │ │ ├── Examples │ │ │ ├── ExampleActionsScreen.php │ │ │ ├── ExampleCardsScreen.php │ │ │ ├── ExampleChartsScreen.php │ │ │ ├── ExampleFieldsAdvancedScreen.php │ │ │ ├── ExampleFieldsScreen.php │ │ │ ├── ExampleGridScreen.php │ │ │ ├── ExampleLayoutsScreen.php │ │ │ ├── ExampleScreen.php │ │ │ └── ExampleTextEditorsScreen.php │ │ │ ├── PlatformScreen.php │ │ │ ├── Role │ │ │ ├── RoleEditScreen.php │ │ │ └── RoleListScreen.php │ │ │ └── User │ │ │ ├── UserEditScreen.php │ │ │ ├── UserListScreen.php │ │ │ └── UserProfileScreen.php │ ├── User.stub │ └── routes │ │ └── platform.php ├── chart.stub ├── field.blade.stub ├── field.stub ├── filters.stub ├── listener.stub ├── presenter.stub ├── rows.stub ├── screen.stub ├── selection.stub ├── tabMenu.stub └── table.stub └── vite.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "@babel/plugin-proposal-class-properties", 4 | "@babel/plugin-transform-block-scoping" 5 | ], 6 | "presets": [ 7 | [ 8 | "@babel/preset-env", 9 | { 10 | "modules": false 11 | } 12 | ] 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "jquery": true 7 | }, 8 | "rules": { 9 | "indent": [ 10 | "error", 11 | 4 12 | ], 13 | "linebreak-style": [ 14 | "error", 15 | "unix" 16 | ], 17 | "quotes": [ 18 | "error", 19 | "single" 20 | ], 21 | "class-methods-use-this": 0, 22 | "radix": ["error", "as-needed"] 23 | }, 24 | "extends": "airbnb-base", 25 | "globals": { 26 | "axios": true, 27 | "Turbolinks": true 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Chernyaev Alexandr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /database/factories/AttachmentFactory.php: -------------------------------------------------------------------------------- 1 | Str::random(), 29 | 'original_name' => Str::random(), 30 | 'mime' => 'unknown', 31 | 'extension' => 'unknown', 32 | 'size' => random_int(1, 100), 33 | 'sort' => random_int(1, 100), 34 | 'path' => Str::random(), 35 | 'description' => Str::random(), 36 | 'alt' => Str::random(), 37 | 'hash' => Str::random(), 38 | 'disk' => 'public', 39 | 'group' => null, 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /database/migrations/2015_04_12_000000_create_orchid_users_table.php: -------------------------------------------------------------------------------- 1 | jsonb('permissions')->nullable(); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('users', function (Blueprint $table) { 25 | $table->dropColumn(['permissions']); 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/migrations/2015_10_19_214424_create_orchid_roles_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 16 | $table->string('slug')->unique(); 17 | $table->string('name'); 18 | $table->jsonb('permissions')->nullable(); 19 | $table->timestamps(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | */ 26 | public function down(): void 27 | { 28 | Schema::dropIfExists('roles'); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /database/migrations/2015_10_19_214425_create_orchid_role_users_table.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('user_id'); 16 | $table->unsignedInteger('role_id'); 17 | $table->primary(['user_id', 'role_id']); 18 | $table->foreign('user_id') 19 | ->references('id') 20 | ->on('users') 21 | ->onUpdate('cascade') 22 | ->onDelete('cascade'); 23 | $table->foreign('role_id') 24 | ->references('id') 25 | ->on('roles') 26 | ->onUpdate('cascade') 27 | ->onDelete('cascade'); 28 | }); 29 | } 30 | 31 | /** 32 | * Reverse the migrations. 33 | */ 34 | public function down(): void 35 | { 36 | Schema::dropIfExists('role_users'); 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /database/migrations/2017_09_17_125801_create_notifications_table.php: -------------------------------------------------------------------------------- 1 | uuid('id')->primary(); 19 | $table->string('type'); 20 | $table->morphs('notifiable'); 21 | $table->text('data'); 22 | $table->timestamp('read_at')->nullable(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down(): void 34 | { 35 | Schema::dropIfExists('notifications'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /database/seeders/OrchidDatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call([ 22 | // AttachmentsTableSeeder::class, 23 | // UsersTableSeeder::class, 24 | // RolesTableSeeder::class, 25 | // SettingsTableSeeder::class, 26 | ]); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database/seeders/RolesTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /database/seeders/UsersTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "build": "vite build" 5 | }, 6 | "dependencies": { 7 | "@babel/plugin-proposal-class-properties": "^7.13.0", 8 | "@babel/plugin-transform-block-scoping": "^7.12.1", 9 | "@babel/preset-env": "^7.13.15", 10 | "@hotwired/stimulus": "^3.1.0", 11 | "@hotwired/turbo": "^8.0.2", 12 | "@popperjs/core": "^2.9.2", 13 | "axios": "^1.1.3", 14 | "bootstrap": "~5.3.0", 15 | "codeflask": "^1.4.0", 16 | "cropperjs": "^1.5.11", 17 | "cross-env": "^7.0.0", 18 | "dropzone": "^5.9.2", 19 | "flatpickr": "^4.6.3", 20 | "frappe-charts": "^1.6.1", 21 | "inputmask": "^5.0.6", 22 | "laravel-mix": "^6.0.16", 23 | "leaflet": "^1.7.1", 24 | "quill": "^2.0.0", 25 | "simplemde": "^1.11", 26 | "sortablejs": "^1.13.0", 27 | "tom-select": "^2.3.1", 28 | "postcss": "^8.2.10", 29 | "rtlcss": "^4.0.0", 30 | "sass": "^1.69.7", 31 | "sass-loader": "^16.0.5", 32 | "vite-plugin-rtl-css": "^1.0.6", 33 | "vue-template-compiler": "^2.6.12", 34 | "stimulus-vite-helpers": "^3.0.1", 35 | "vite-plugin-manifest-sri": "^0.2.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /psalm.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources/js/app.js": { 3 | "file": "assets/app.js?v=6d507ed2", 4 | "isEntry": true, 5 | "src": "resources/js/app.js", 6 | "integrity": "sha384-r0qKRGCKpByrh/uftoOOc4So8tVNZJezahxoDhUFcvUVetOvuEhOqzewSUzQ2XTN" 7 | }, 8 | "resources/sass/app.scss": { 9 | "file": "assets/app.css?v=af1ca96b", 10 | "isEntry": true, 11 | "src": "resources/sass/app.scss", 12 | "integrity": "sha384-+JqLG6zZecAiFDFxLSiTiLmEPwXoZLx0u5yQwWjQhrhcIOPgk2+hLAGeY+ZN6OGL" 13 | } 14 | } -------------------------------------------------------------------------------- /resources/js/app.js: -------------------------------------------------------------------------------- 1 | import * as Turbo from '@hotwired/turbo'; 2 | import * as Bootstrap from 'bootstrap'; 3 | import { Application } from '@hotwired/stimulus'; 4 | import ApplicationController from './controllers/application_controller'; 5 | import Orchid from "./orchid"; 6 | import { registerControllers } from 'stimulus-vite-helpers'; 7 | 8 | window.Turbo = Turbo; 9 | window.Bootstrap = Bootstrap; 10 | window.application = Application.start(); 11 | window.Controller = ApplicationController; 12 | window.Orchid = Orchid; 13 | 14 | const controllers = import.meta.glob('./**/*_controller.js', { eager: true }); 15 | registerControllers(application, controllers); 16 | 17 | window.addEventListener('turbo:before-fetch-request', (event) => { 18 | let state = document.getElementById('screen-state')?.value; 19 | 20 | if (state && state.length > 0) { 21 | event.detail?.fetchOptions?.body?.append('_state', state); 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /resources/js/controllers/browsing_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | 3 | export default class extends ApplicationController { 4 | 5 | /** 6 | * 7 | */ 8 | connect() { 9 | // Selecting the iframe element 10 | var iframe = this.element.querySelector('iframe'); 11 | 12 | // Resize for SPA 13 | this.resizeTimer = setInterval(() => { 14 | // Set color background 15 | iframe.contentDocument.body.style.backgroundColor = 'initial'; 16 | iframe.contentDocument.body.style.overflow = 'hidden'; 17 | 18 | let body = iframe.contentWindow.document.body; 19 | 20 | iframe.contentDocument.body.style.height = 'inherit' 21 | iframe.style.height = Math.max(body.scrollHeight, body.offsetHeight) + 'px'; 22 | }, 100); 23 | } 24 | 25 | disconnect() { 26 | clearTimeout(this.resizeTimer); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /resources/js/controllers/button_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | 3 | export default class extends ApplicationController { 4 | 5 | /** 6 | * 7 | * @param event 8 | * @returns {boolean} 9 | */ 10 | confirm(event) { 11 | let button = this.element.outerHTML 12 | .replace('btn-link', 'btn-default') 13 | .replace(/data-action="(.*?)"/g, ''); 14 | 15 | this.application 16 | .getControllerForElementAndIdentifier(this.confirmModal, 'confirm') 17 | .open({ 18 | 'message': this.data.get('confirm'), 19 | 'button': button, 20 | }); 21 | 22 | event.preventDefault(); 23 | return false; 24 | } 25 | 26 | 27 | /** 28 | * 29 | * @returns {HTMLElement} 30 | */ 31 | get confirmModal() { 32 | return document.getElementById(`confirm-dialog`); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /resources/js/controllers/checkbox_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | 3 | export default class extends ApplicationController { 4 | /** 5 | * 6 | */ 7 | connect() { 8 | const checkbox = this.element.querySelector('input:not([hidden])'); 9 | 10 | if (checkbox) { 11 | checkbox.indeterminate = this.data.get('indeterminate') 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /resources/js/controllers/code_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | import CodeFlask from 'codeflask'; 3 | 4 | 5 | export default class extends ApplicationController { 6 | /** 7 | * 8 | */ 9 | connect() { 10 | const input = this.element.querySelector('input'); 11 | 12 | const flask = new CodeFlask(this.element.querySelector('.code'), { 13 | language: this.data.get('language'), 14 | lineNumbers: this.data.get('lineNumbers'), 15 | defaultTheme: this.data.get('defaultTheme'), 16 | readonly: input.readOnly, 17 | }); 18 | 19 | flask.updateCode(input.value); 20 | 21 | flask.onUpdate((code) => { 22 | input.value = code; 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /resources/js/controllers/confirm_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | import {Modal} from "bootstrap"; 3 | 4 | export default class extends ApplicationController { 5 | 6 | /** 7 | * 8 | * @type {[string, string]} 9 | */ 10 | static targets = ["message", "button"] 11 | 12 | /** 13 | * 14 | * @param message 15 | */ 16 | setMessage(message) { 17 | this.messageTarget.innerHTML = message; 18 | 19 | return this; 20 | } 21 | 22 | /** 23 | * 24 | * @param button 25 | */ 26 | setButton(button) { 27 | this.buttonTarget.innerHTML = button; 28 | 29 | return this; 30 | } 31 | 32 | /** 33 | * 34 | */ 35 | open(options) { 36 | this 37 | .setButton(options.button) 38 | .setMessage(options.message); 39 | 40 | /** 41 | * Added focus button for Mac OS firefox/safari 42 | */ 43 | document.querySelectorAll('button[type=submit]').forEach((button) => { 44 | button.addEventListener('click', (event) => { 45 | event.target.focus(); 46 | }); 47 | }); 48 | 49 | (new Modal(this.element)).show(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /resources/js/controllers/input_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | import Inputmask from 'inputmask'; 3 | 4 | export default class extends ApplicationController { 5 | 6 | /** 7 | * 8 | * @returns {string|object} 9 | */ 10 | get mask() { 11 | let mask = this.data.get('mask'); 12 | 13 | try { 14 | mask = JSON.parse(mask); 15 | mask.autoUnmask = mask.autoUnmask || mask.removeMaskOnSubmit || undefined; 16 | 17 | return mask; 18 | } catch (e) { 19 | // as string 20 | return mask; 21 | } 22 | } 23 | 24 | /** 25 | * 26 | */ 27 | connect() { 28 | const element = this.element.querySelector('input'); 29 | let mask = this.mask; 30 | 31 | // mask 32 | if (mask.length < 1) { 33 | return; 34 | } 35 | 36 | let form = element.form || this.element.closest('form') 37 | 38 | form.addEventListener('orchid:screen-submit', () => { 39 | if (mask.removeMaskOnSubmit) { 40 | element.inputmask.remove(); 41 | } 42 | }); 43 | 44 | Inputmask(mask).mask(element); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /resources/js/controllers/menu_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | 3 | export default class extends ApplicationController { 4 | 5 | /** 6 | * 7 | */ 8 | toggle(event) { 9 | document.body.classList.toggle('menu-open'); 10 | event.preventDefault(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /resources/js/controllers/password_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | 3 | export default class extends ApplicationController { 4 | 5 | /** 6 | * 7 | * @type {string[]} 8 | */ 9 | static targets = [ 10 | 'password', 11 | 'iconShow', 12 | 'iconLock' 13 | ]; 14 | 15 | /** 16 | * 17 | */ 18 | change() { 19 | const currentType = this.passwordTarget.type; 20 | let type = 'password'; 21 | 22 | if(currentType === 'text'){ 23 | this.iconLockTarget.classList.add('none'); 24 | this.iconShowTarget.classList.remove('none'); 25 | } 26 | 27 | if (currentType === 'password') { 28 | type = 'text'; 29 | this.iconLockTarget.classList.remove('none'); 30 | this.iconShowTarget.classList.add('none'); 31 | } 32 | 33 | this.passwordTarget.setAttribute('type', type); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /resources/js/controllers/popover_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | import {Popover} from 'bootstrap'; 3 | 4 | export default class extends ApplicationController { 5 | /** 6 | * 7 | */ 8 | connect() { 9 | this.popover = new Popover(this.element); 10 | } 11 | 12 | /** 13 | * 14 | * @param event 15 | */ 16 | trigger(event) { 17 | event.preventDefault(); 18 | this.popover.toggle(); 19 | } 20 | 21 | /** 22 | * Destroy popover on disconnect 23 | */ 24 | disconnect() { 25 | this.popover.dispose(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /resources/js/controllers/pull-to-refresh_controller.js: -------------------------------------------------------------------------------- 1 | import {Controller} from '@hotwired/stimulus'; 2 | 3 | export default class extends Controller { 4 | /** 5 | * 6 | * @param event 7 | */ 8 | touchstart(event) { 9 | this.startPageY = event.touches[0].screenY; 10 | } 11 | 12 | /** 13 | * 14 | * @param event 15 | */ 16 | touchmove(event) { 17 | 18 | if (this.willRefresh) { 19 | return 20 | } 21 | 22 | const scrollTop = document.body.scrollTop 23 | const dy = event.changedTouches[0].screenY - this.startPageY 24 | 25 | if (scrollTop < 1 && dy > 150) { 26 | this.willRefresh = true; 27 | this.element.style = 'filter: blur(1px);opacity: 0.2;touch-action: none;'; 28 | } 29 | } 30 | 31 | /** 32 | * 33 | * @param event 34 | */ 35 | touchend(event) { 36 | if (this.willRefresh) { 37 | Turbo.visit(window.location.toString(), {action: 'replace'}); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /resources/js/controllers/radiobutton_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | 3 | export default class extends ApplicationController { 4 | /** 5 | * 6 | */ 7 | checked(event) { 8 | event.target.offsetParent.querySelectorAll('input').forEach((input) => { 9 | input.removeAttribute('checked'); 10 | }); 11 | event.target.offsetParent.querySelectorAll('label').forEach((label) => { 12 | label.classList.remove('active'); 13 | }); 14 | event.target.classList.add('active'); 15 | event.target.setAttribute('checked', 'checked'); 16 | event.target.dispatchEvent(new Event("change")); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /resources/js/controllers/reload_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | 3 | export default class extends ApplicationController { 4 | 5 | /** 6 | * 7 | */ 8 | connect() { 9 | const url = this.data.get('url'); 10 | const method = this.data.get('method') || 'get'; 11 | 12 | /* Time in seconds */ 13 | const interval = this.data.get('interval') || 1000; 14 | 15 | setInterval(() => { 16 | axios({ method, url }).then((response) => { 17 | this.element.innerHTML = response.data; 18 | }); 19 | }, interval); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/js/controllers/toggle_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | 3 | export default class extends ApplicationController { 4 | static targets = ["button"] 5 | 6 | toggle() { 7 | this.buttonTarget.click() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /resources/js/controllers/tooltip_controller.js: -------------------------------------------------------------------------------- 1 | import ApplicationController from "./application_controller"; 2 | import {Tooltip} from 'bootstrap'; 3 | 4 | export default class extends ApplicationController { 5 | 6 | /** 7 | * 8 | */ 9 | connect() { 10 | this.tooltip = new Tooltip(this.element, { 11 | boundary: 'window' 12 | }) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /resources/js/controllers/viewport-entrance-toggle_controller.js: -------------------------------------------------------------------------------- 1 | import { Controller } from '@hotwired/stimulus'; 2 | 3 | export default class extends Controller { 4 | initialize() { 5 | this.intersectionObserver = new IntersectionObserver((entries) => this.processIntersectionEntries(entries)); 6 | } 7 | 8 | connect() { 9 | this.intersectionObserver.observe(this.element); 10 | } 11 | 12 | disconnect() { 13 | this.intersectionObserver.unobserve(this.element); 14 | } 15 | 16 | // Private 17 | processIntersectionEntries(entries) { 18 | entries.forEach((entry) => { 19 | this.element.classList.toggle(this.data.get('class'), entry.isIntersecting && window.document.body.scrollHeight > window.document.body.clientHeight + 400); 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /resources/js/orchid.js: -------------------------------------------------------------------------------- 1 | const Orchid = { 2 | /** 3 | * Registers a controller with the application router. 4 | * Registers the provided controller definition directly. 5 | * 6 | * @param {string} name - The unique name of the controller. 7 | * @param {Object} definition - The controller definition. 8 | */ 9 | register(name, definition) { 10 | if (application.router.modulesByIdentifier.has(name)) { 11 | console.warn(`Controller with name "${name}" already exists.`); 12 | return; 13 | } 14 | 15 | application.register(name, definition); 16 | }, 17 | }; 18 | 19 | export default Orchid; 20 | -------------------------------------------------------------------------------- /resources/sass/app.scss: -------------------------------------------------------------------------------- 1 | // Core variables and mixins 2 | @import "theme/variables"; 3 | 4 | // Vendor 5 | @import "bootstrap/scss/bootstrap"; 6 | @import "dropzone/dist/basic"; 7 | @import "dropzone/dist/dropzone"; 8 | @import "cropperjs/dist/cropper"; 9 | @import "simplemde/dist/simplemde.min"; 10 | @import "flatpickr/dist/flatpickr.min"; 11 | @import "leaflet/dist/leaflet"; 12 | @import "quill/dist/quill.snow"; 13 | @import "frappe-charts/src/css/charts"; 14 | @import "tom-select/dist/scss/tom-select.bootstrap5"; 15 | 16 | // App 17 | @import "core/mixins"; 18 | @import "core/reset"; 19 | @import "core/layout"; 20 | @import "core/buttons"; 21 | @import "core/modals"; 22 | @import "plugins/plugin"; 23 | @import "core/utilities"; 24 | @import "core/tables"; 25 | @import "core/form"; 26 | @import "plugins/dropzone"; 27 | @import "plugins/load-opacity"; 28 | @import "plugins/accordion"; 29 | @import "plugins/tom-select"; 30 | -------------------------------------------------------------------------------- /resources/sass/plugins/accordion.scss: -------------------------------------------------------------------------------- 1 | .accordion-heading { 2 | svg { 3 | transition: all 340ms; 4 | } 5 | 6 | &:not(.collapsed) { 7 | svg { 8 | transform: rotate(90deg); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /resources/sass/plugins/load-opacity.scss: -------------------------------------------------------------------------------- 1 | .turbo-progress-bar { 2 | height: 2px; 3 | background-color: $primary; 4 | } 5 | 6 | .dropdown-menu { 7 | &.show { 8 | animation: smooth-appearance 240ms ease-in; 9 | } 10 | } 11 | 12 | .media-results *{ 13 | animation: smooth-appearance 240ms ease-in; 14 | } 15 | 16 | 17 | @keyframes smooth-appearance { 18 | 0% { 19 | opacity: 0.1; 20 | } 21 | 25% { 22 | opacity: 0.5; 23 | } 24 | 50% { 25 | opacity: 0.8; 26 | } 27 | 100% { 28 | opacity: 1; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /resources/sass/plugins/tom-select.scss: -------------------------------------------------------------------------------- 1 | .ts-control { 2 | box-shadow: none !important; 3 | } 4 | 5 | .ts-control > input { 6 | min-width: auto; 7 | } 8 | -------------------------------------------------------------------------------- /resources/views/actions/button.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 | 17 | @endcomponent 18 | -------------------------------------------------------------------------------- /resources/views/actions/dropdown.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 | 14 | 15 | 22 | @endcomponent 23 | -------------------------------------------------------------------------------- /resources/views/actions/link.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 | 6 | @isset($icon) 7 | 8 | @endisset 9 | 10 | {{ $name ?? '' }} 11 | 12 | @endcomponent 13 | -------------------------------------------------------------------------------- /resources/views/actions/menu.blade.php: -------------------------------------------------------------------------------- 1 | @isset($title) 2 | 5 | @endisset 6 | 7 | @if (!empty($name)) 8 | 23 | @endif 24 | 25 | @if(!empty($list)) 26 | 41 | @endif 42 | 43 | @if($divider) 44 |
  • 45 | @endif 46 | 47 | -------------------------------------------------------------------------------- /resources/views/actions/modal.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 | 22 | @endcomponent 23 | -------------------------------------------------------------------------------- /resources/views/actions/toggle.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    3 | 9 | 10 | 11 | 22 |
    23 | @endcomponent 24 | -------------------------------------------------------------------------------- /resources/views/auth.blade.php: -------------------------------------------------------------------------------- 1 | @extends('platform::app') 2 | 3 | @section('body') 4 | 5 |
    6 |
    7 | 8 | 9 | @includeFirst([config('platform.template.header'), 'platform::header']) 10 | 11 | 12 |
    13 |
    14 | 15 |
    16 | @yield('content') 17 |
    18 |
    19 |
    20 | 21 | 22 | @includeFirst([config('platform.template.footer'), 'platform::footer']) 23 |
    24 |
    25 | 26 | @endsection 27 | -------------------------------------------------------------------------------- /resources/views/auth/impersonation.blade.php: -------------------------------------------------------------------------------- 1 | @extends('platform::auth') 2 | @section('title',__('Access Denied: Viewing as Another User')) 3 | 4 | @section('content') 5 |

    {{__('Limited Access')}}

    6 | 7 |
    13 | @csrf 14 | 15 |

    16 | {{ __("You are currently viewing this page on behalf of a user who does not have access to it. To return to viewing as yourself, please click the 'Switch to My Account' button. It's possible that the page may be displayed correctly when viewed from your own account.") }} 17 |

    18 | 19 | 22 | 23 |
    24 | @endsection 25 | -------------------------------------------------------------------------------- /resources/views/auth/login.blade.php: -------------------------------------------------------------------------------- 1 | @extends('platform::auth') 2 | @section('title',__('Sign in to your account')) 3 | 4 | @section('content') 5 |

    {{__('Sign in to your account')}}

    6 | 7 |
    14 | @csrf 15 | 16 | @includeWhen($isLockUser,'platform::auth.lockme') 17 | @includeWhen(!$isLockUser,'platform::auth.signin') 18 |
    19 | @endsection 20 | -------------------------------------------------------------------------------- /resources/views/components/notification.blade.php: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 14 | 15 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /resources/views/components/popover.blade.php: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /resources/views/components/stream.blade.php: -------------------------------------------------------------------------------- 1 | @props(['target', 'action', 'push', 'rule' => \Orchid\Support\Facades\Dashboard::isPartialRequest()]) 2 | 3 | 4 | @if(filter_var($rule, FILTER_VALIDATE_BOOLEAN)) 5 | @fragment($target) 6 | 7 | 10 | 11 | @endfragment 12 | @elseif(!empty($push)) 13 | @push($push) 14 | {!! $slot !!} 15 | @endpush 16 | @else 17 | {!! $slot !!} 18 | @endif 19 | -------------------------------------------------------------------------------- /resources/views/dummy/block.blade.php: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |

    Dummy {{ Str::random(8) }}

    4 |
    5 |
    6 | -------------------------------------------------------------------------------- /resources/views/errors/404.blade.php: -------------------------------------------------------------------------------- 1 | @extends('platform::dashboard') 2 | 3 | @section('title', '404') 4 | @section('description', __("You requested a page that doesn't exist.")) 5 | 6 | @section('content') 7 | 8 |
    9 |

    10 | {{ __("Sorry, we don't have anything to show you on this page") }} 11 |

    12 | 13 | 14 |

    {{ __("This could be because:") }}

    15 | 20 | 21 |

    {{ __("If you think you should have access to this page, ask the person who manages the project (or the account) to add you to it.") }}

    22 |
    23 | 24 | @endsection 25 | -------------------------------------------------------------------------------- /resources/views/fields/checkbox.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    4 | @isset($sendTrueOrFalse) 5 | 6 |
    7 | 11 | 12 |
    13 | @else 14 |
    15 | 18 | 19 |
    20 | @endisset 21 |
    22 | @endcomponent 23 | -------------------------------------------------------------------------------- /resources/views/fields/code.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    8 |
    9 | 10 |
    11 | @endcomponent 12 | -------------------------------------------------------------------------------- /resources/views/fields/dataRange.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    6 |
    7 |
    8 | 15 |
    16 |
    17 | 18 |
    19 |
    20 | 27 |
    28 |
    29 |
    30 | @endcomponent 31 | -------------------------------------------------------------------------------- /resources/views/fields/datetime.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    6 | 12 | 13 | @if(true === $allowEmpty) 14 |
    15 | 18 | 19 | 20 |
    21 | @endif 22 | 23 | @foreach($quickDates as $name => $value) 24 | 27 | @endforeach 28 |
    29 | @endcomponent 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /resources/views/fields/group.blade.php: -------------------------------------------------------------------------------- 1 |
    $widthColumns !== null, 5 | ])> 6 | @foreach($group as $field) 7 |
    10 | {!! $field !!} 11 |
    12 | @endforeach 13 |
    14 | -------------------------------------------------------------------------------- /resources/views/fields/input.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    5 | 6 |
    7 | 8 | @empty(!$datalist) 9 | 10 | @foreach($datalist as $item) 11 | 14 | @endempty 15 | @endcomponent 16 | -------------------------------------------------------------------------------- /resources/views/fields/label.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 | @if(strlen($value) > 0) 3 |

    4 | {{ $value }} 5 |

    6 | @endif 7 | @endcomponent 8 | -------------------------------------------------------------------------------- /resources/views/fields/matrix.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 | 8 | 9 | 10 | @foreach($columns as $key => $column) 11 | 14 | @endforeach 15 | 16 | 17 | 18 | 19 | @foreach($value as $key => $row) 20 | @include('platform::partials.fields.matrixRow',['row' => $row, 'key' => $key]) 21 | @endforeach 22 | 23 | 24 | 31 | 32 | 33 | 36 | 37 |
    12 | {{ is_int($key) ? $column : $key }} 13 |
    25 | 26 | 27 | 28 | {{ __($addRowLabel) }} 29 | 30 |
    38 | @endcomponent 39 | -------------------------------------------------------------------------------- /resources/views/fields/numberRange.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    3 |
    4 |
    5 | 12 |
    13 |
    14 | 15 |
    16 |
    17 | 24 |
    25 |
    26 |
    27 | @endcomponent 28 | -------------------------------------------------------------------------------- /resources/views/fields/password.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 | 3 |
    6 | 7 |
    8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 |
    18 | 19 | @endcomponent 20 | -------------------------------------------------------------------------------- /resources/views/fields/quill.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    9 |
    10 |
    12 |
    13 | 14 |
    15 | @endcomponent 16 | -------------------------------------------------------------------------------- /resources/views/fields/radio.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    3 | 4 | 5 |
    6 | @endcomponent 7 | -------------------------------------------------------------------------------- /resources/views/fields/radiobutton.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    3 |
    4 | 5 | @foreach($options as $key => $option) 6 | 13 | @endforeach 14 |
    15 |
    16 | @endcomponent 17 | -------------------------------------------------------------------------------- /resources/views/fields/range.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 | 3 | @endcomponent 4 | -------------------------------------------------------------------------------- /resources/views/fields/relation.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    18 | 23 |
    24 | @endcomponent 25 | -------------------------------------------------------------------------------- /resources/views/fields/select.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    9 | 21 |
    22 | @endcomponent 23 | -------------------------------------------------------------------------------- /resources/views/fields/simplemde.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 |
    4 | 5 | 6 |
    7 | @endcomponent 8 | -------------------------------------------------------------------------------- /resources/views/fields/switch.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 | @isset($sendTrueOrFalse) 3 | 4 |
    5 | 10 | 11 |
    12 | @else 13 |
    14 | 18 | 19 |
    20 | @endisset 21 | @endcomponent 22 | -------------------------------------------------------------------------------- /resources/views/fields/textarea.blade.php: -------------------------------------------------------------------------------- 1 | @component($typeForm, get_defined_vars()) 2 | 3 | @endcomponent 4 | -------------------------------------------------------------------------------- /resources/views/header.blade.php: -------------------------------------------------------------------------------- 1 | @push('head') 2 | 3 | 4 | 11 | 12 | 13 | 14 | @endpush 15 | 16 |
    17 | @auth 18 | 19 | @endauth 20 | 21 |

    22 | {{ config('app.name') }} 23 |

    24 |
    25 | -------------------------------------------------------------------------------- /resources/views/layouts/accordion.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | @foreach($manyForms as $name => $forms) 3 | @php 4 | $collapseId = 'collapse-' . \Illuminate\Support\Str::slug($name); 5 | $collapseIsOpen = in_array($name, $open); 6 | @endphp 7 | 8 | 17 | 18 | {!! $name !!} 19 | 20 | 21 |
    28 | @foreach($forms as $form) 29 | {!! $form !!} 30 | @endforeach 31 |
    32 | @endforeach 33 |
    34 | -------------------------------------------------------------------------------- /resources/views/layouts/blank.blade.php: -------------------------------------------------------------------------------- 1 | @foreach($manyForms as $key => $column) 2 | @foreach(\Illuminate\Support\Arr::wrap($column) as $item) 3 | {!! $item ?? '' !!} 4 | @endforeach 5 | @endforeach 6 | -------------------------------------------------------------------------------- /resources/views/layouts/block.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | @if(!empty($title) || !empty($description)) 3 |
    4 | 5 | {{ __($title ?? '') }} 6 | 7 | @if(!empty($description)) 8 |

    9 | {!! __($description ?? '') !!} 10 |

    11 | @endif 12 |
    13 |
    14 | @endif 15 |
    16 | 17 |
    18 | @foreach($manyForms as $key => $layouts) 19 | @foreach($layouts as $layout) 20 | {!! $layout ?? '' !!} 21 | @endforeach 22 | @endforeach 23 |
    24 | 25 | @empty(!$commandBar) 26 |
    27 | @foreach($commandBar as $command) 28 |
    29 | {!! $command !!} 30 |
    31 | @endforeach 32 |
    33 | @endempty 34 |
    35 |
    36 | 37 | -------------------------------------------------------------------------------- /resources/views/layouts/browsing.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | -------------------------------------------------------------------------------- /resources/views/layouts/columns.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | @foreach($manyForms as $key => $column) 3 |
    4 | @foreach($column as $item) 5 | {!! $item ?? '' !!} 6 | @endforeach 7 |
    8 | @endforeach 9 |
    10 | -------------------------------------------------------------------------------- /resources/views/layouts/facepile.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | @foreach($users as $user) 3 | 9 | {{ $user->title() }} 12 | 13 | @endforeach 14 |
    15 | 16 | -------------------------------------------------------------------------------- /resources/views/layouts/filter.blade.php: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | @foreach ($filters as $filter) 4 |
    5 | {!! $filter->render() !!} 6 |
    7 | @endforeach 8 |
    9 |
    10 | 13 | 16 |
    17 |
    18 |
    19 |
    20 | 21 | -------------------------------------------------------------------------------- /resources/views/layouts/legend.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | 3 | @empty(!$title) 4 |
    5 | 6 | {{ $title }} 7 | 8 |
    9 | @endempty 10 | 11 |
    12 | @foreach($columns as $column) 13 |
    14 |
    15 | {!! $column->buildDt($repository) !!} 16 |
    17 |
    18 | {!! $column->buildDd($repository) !!} 19 |
    20 |
    21 | @endforeach 22 |
    23 |
    24 | -------------------------------------------------------------------------------- /resources/views/layouts/listener.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
    8 | @foreach($manyForms as $layouts) 9 | @foreach($layouts as $layout) 10 | {!! $layout ?? '' !!} 11 | @endforeach 12 | @endforeach 13 |
    14 |
    15 | -------------------------------------------------------------------------------- /resources/views/layouts/metric.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | @isset($title) 3 | 4 | {{ __($title) }} 5 | 6 | @endisset 7 |
    8 | @foreach($metrics as $key => $metric) 9 |
    10 |
    11 | {{ __($key) }} 12 |

    13 | {{ is_array($metric) ? $metric['value'] : $metric }} 14 | 15 | @if(isset($metric['diff']) && (float)$metric['diff'] !== 0.0) 16 | 17 | {{ round($metric['diff'], 2) }} % 18 | 19 | @endif 20 |

    21 |
    22 |
    23 | @endforeach 24 |
    25 |
    26 | -------------------------------------------------------------------------------- /resources/views/layouts/persona.blade.php: -------------------------------------------------------------------------------- 1 | 2 | @empty(!$image) 3 | 4 | 5 | 6 | @endempty 7 |
    8 |

    {{ $title }}

    9 | {{ $subTitle }} 10 |
    11 |
    12 | -------------------------------------------------------------------------------- /resources/views/layouts/row.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | 3 | @empty(!$title) 4 |
    5 | 6 | {{ $title }} 7 | 8 |
    9 | @endempty 10 | 11 |
    12 | {!! $form ?? '' !!} 13 |
    14 |
    15 | -------------------------------------------------------------------------------- /resources/views/layouts/split.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | @foreach($manyForms as $key => $column) 3 |
    $loop->index % 2 == 0, 6 | $columnClass[1] . ' order-md-last' => $loop->index % 2 != 0, 7 | 'order-first' => $reverseOnPhone && $loop->index % 2 != 0 8 | ])> 9 | @foreach($column as $item) 10 | {!! $item ?? '' !!} 11 | @endforeach 12 |
    13 | @endforeach 14 |
    15 | -------------------------------------------------------------------------------- /resources/views/layouts/tabMenu.blade.php: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /resources/views/partials/alert.blade.php: -------------------------------------------------------------------------------- 1 | @if (session()->has(\Orchid\Alert\Alert::SESSION_MESSAGE)) 2 |
    3 | {!! session(\Orchid\Alert\Alert::SESSION_MESSAGE) !!} 4 | 5 | @yield('flash_notification.sub_message') 6 | 7 |
    8 | @endif 9 | 10 | @empty(!$errors->count()) 11 | 20 | @endif 21 | -------------------------------------------------------------------------------- /resources/views/partials/confirm.blade.php: -------------------------------------------------------------------------------- 1 | 32 | 33 | -------------------------------------------------------------------------------- /resources/views/partials/fields/clear.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | 3 | @isset($title) 4 | 7 | @endisset 8 | 9 | {{$slot}} 10 | 11 | @php 12 | // Backport for consistent error handling behavior between Laravel 10 and 11. 13 | // This implementation will be modified in a future major version. 14 | 15 | // Retrieve all errors from the $errors object and convert them into a collection 16 | $allErrors = collect($errors->all()); 17 | 18 | // Check if there is a 'default' error key in the collection of errors 19 | if ($allErrors->has('default')) { 20 | // If a 'default' error exists, assign it to the $errors variable 21 | $errors = $allErrors->get('default'); 22 | } 23 | @endphp 24 | 25 | @if($errors->has($oldName)) 26 |
    27 | {{$errors->first($oldName)}} 28 |
    29 | @elseif(isset($help)) 30 | {!!$help!!} 31 | @endif 32 |
    33 | -------------------------------------------------------------------------------- /resources/views/partials/fields/matrixRow.blade.php: -------------------------------------------------------------------------------- 1 | 2 | @foreach($columns as $column) 3 | 4 | 5 | {!! 6 | $fields[$column] 7 | ->value($row[$column] ?? '') 8 | ->prefix($name) 9 | ->id("$idPrefix-$key-$column") 10 | ->name($keyValue ? $column : "[$key][$column]") 11 | !!} 12 | 13 | 14 | @if ($loop->last && $removableRows) 15 | 16 | 20 | 21 | 22 | 23 | @endif 24 | @endforeach 25 | 26 | -------------------------------------------------------------------------------- /resources/views/partials/fields/vertical.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | @isset($title) 3 | 10 | @endisset 11 | 12 | {{$slot}} 13 | 14 | @php 15 | // Backport for consistent error handling behavior between Laravel 10 and 11. 16 | // This implementation will be modified in a future major version. 17 | 18 | // Retrieve all errors from the $errors object and convert them into a collection 19 | $allErrors = collect($errors->all()); 20 | 21 | // Check if there is a 'default' error key in the collection of errors 22 | if ($allErrors->has('default')) { 23 | // If a 'default' error exists, assign it to the $errors variable 24 | $errors = $allErrors->get('default'); 25 | } 26 | @endphp 27 | 28 | @if($errors->has($oldName)) 29 |
    30 | {{$errors->first($oldName)}} 31 |
    32 | @elseif(isset($help)) 33 | {!!$help!!} 34 | @endif 35 |
    36 | 37 | @isset($hr) 38 |
    39 | @endisset 40 | -------------------------------------------------------------------------------- /resources/views/partials/layouts/dt.blade.php: -------------------------------------------------------------------------------- 1 | {{$title}} 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/views/partials/layouts/filter.blade.php: -------------------------------------------------------------------------------- 1 | 22 | -------------------------------------------------------------------------------- /resources/views/partials/layouts/selectedTd.blade.php: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /resources/views/partials/layouts/td.blade.php: -------------------------------------------------------------------------------- 1 | $width, 5 | "$style" => $style, 6 | ]) 7 | > 8 |
    9 | @isset($render) 10 | {!! $value !!} 11 | @else 12 | {{ $value }} 13 | @endisset 14 |
    15 | 16 | -------------------------------------------------------------------------------- /resources/views/partials/layouts/th.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 | @includeWhen($filter !== null, "platform::partials.layouts.filter", ['filter' => $filter]) 5 | 6 | @if($sort) 7 | 9 | {!! $title !!} 10 | 11 | 12 | 13 | @if(is_sort($column)) 14 | @php $sortIcon = get_sort($column) === 'desc' ? 'bs.sort-down' : 'bs.sort-up' @endphp 15 | 16 | @endif 17 | 18 | @else 19 | {!! $title !!} 20 | 21 | 22 | @endif 23 |
    24 | 25 | @if($filterString) 26 |
    27 | 31 | {{ $filterString }} 32 | 33 | 34 |
    35 | @endif 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /resources/views/partials/notification-wrap.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | {!! $table !!} 3 |
    4 | -------------------------------------------------------------------------------- /resources/views/partials/notification.blade.php: -------------------------------------------------------------------------------- 1 | 22 | -------------------------------------------------------------------------------- /resources/views/partials/profile.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 | @if($image = Auth::user()->presenter()->image()) 5 | {{ Auth::user()->presenter()->title()}} 6 | @endif 7 | 8 | 9 | {{Auth::user()->presenter()->title()}} 10 | {{Auth::user()->presenter()->subTitle()}} 11 | 12 | 13 | 14 | 15 | 16 |
    17 | -------------------------------------------------------------------------------- /resources/views/partials/result.blade.php: -------------------------------------------------------------------------------- 1 | @section('search', $query) 2 | 3 | @empty(!$radios) 4 | 5 | {!! $radios !!} 6 | 7 | @endempty 8 | 9 |
    10 | @forelse($results as $item) 11 | 12 | 13 | 14 | @empty(!$item->image()) 15 | 16 | {{$item->title()}} 17 | 18 | @endempty 19 | 20 | 21 | {{$item->title()}} 22 | 23 | {{$item->subTitle()}} 24 | 25 | 26 | 27 | @empty 28 | 29 |
    30 |

    31 | 32 | 33 | {{ __('Nothing found.') }} 34 |

    35 | 36 | {{ __('Try changing the query or type.') }} 37 |
    38 | @endforelse 39 | 40 |
    41 | @includeWhen($results instanceof \Illuminate\Contracts\Pagination\Paginator && $results->isNotEmpty(), 42 | 'platform::layouts.pagination', 43 | ['paginator' => $results] 44 | ) 45 |
    46 |
    47 | 48 | 49 | -------------------------------------------------------------------------------- /resources/views/partials/search.blade.php: -------------------------------------------------------------------------------- 1 | @if(Dashboard::getSearch()->isNotEmpty()) 2 |
    3 |
    4 |
    5 | 9 |
    10 | 11 |
    12 |
    13 | 17 |
    18 |
    19 | @else 20 |
    21 | @endif 22 | -------------------------------------------------------------------------------- /resources/views/partials/state.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /resources/views/partials/update-assets.blade.php: -------------------------------------------------------------------------------- 1 | @if(!Dashboard::assetsAreCurrent()) 2 |
    3 |
    4 | 5 |

    {{ __("Complete the update.") }}

    6 |
    7 | 8 |

    {{ __("The published Orchid assets are not up-to-date with the installed version. To update, run:") }}

    9 | php artisan orchid:publish 10 |
    11 | @endif 12 | -------------------------------------------------------------------------------- /resources/views/workspace/compact.blade.php: -------------------------------------------------------------------------------- 1 | @extends('platform::app') 2 | 3 | @section('body') 4 | 5 |
    6 |
    7 | @yield('workspace') 8 | 9 | @includeFirst([config('platform.template.footer'), 'platform::footer']) 10 |
    11 |
    12 | 13 | @endsection 14 | -------------------------------------------------------------------------------- /resources/views/workspace/full.blade.php: -------------------------------------------------------------------------------- 1 | @extends('platform::app') 2 | 3 | @section('body') 4 | 5 |
    6 |
    7 | @yield('workspace') 8 | 9 | @includeFirst([config('platform.template.footer'), 'platform::footer']) 10 |
    11 |
    12 | 13 | @endsection 14 | -------------------------------------------------------------------------------- /routes/auth.php: -------------------------------------------------------------------------------- 1 | name('login'); 12 | Route::middleware('throttle:60,1') 13 | ->post('login', [LoginController::class, 'login']) 14 | ->name('login.auth'); 15 | 16 | Route::get('lock', [LoginController::class, 'resetCookieLockMe'])->name('login.lock'); 17 | } 18 | 19 | Route::get('switch-logout', [LoginController::class, 'switchLogout']); 20 | Route::post('switch-logout', [LoginController::class, 'switchLogout'])->name('switch.logout'); 21 | Route::post('logout', [LoginController::class, 'logout'])->name('logout'); 22 | -------------------------------------------------------------------------------- /src/Access/RoleInterface.php: -------------------------------------------------------------------------------- 1 | attachments($group); 29 | } 30 | 31 | /** 32 | * Get all the attachments associated with the given model. 33 | * 34 | * @param string|null $group 35 | * 36 | * @return MorphToMany 37 | */ 38 | public function attachments(?string $group = null): MorphToMany 39 | { 40 | return $this->morphToMany( 41 | Dashboard::model(Attachment::class), 42 | 'attachmentable', 43 | 'attachmentable', 44 | 'attachmentable_id', 45 | 'attachment_id' 46 | ) 47 | ->when($group !== null, fn ($query) => $query->where('group', $group)) 48 | ->orderBy('sort'); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Attachment/Contracts/Engine.php: -------------------------------------------------------------------------------- 1 | column]; 29 | } 30 | 31 | /** 32 | * Retrieves the value of the filter from the HTTP request. 33 | * 34 | * @return mixed The value of the filter input from the request, or null if not present. 35 | */ 36 | public function getHttpValue(): mixed 37 | { 38 | return $this->request->input('filter.'.$this->column); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Filters/Types/Ilike.php: -------------------------------------------------------------------------------- 1 | where( 15 | $this->column, 16 | 'ILIKE', 17 | '%'.$this->getHttpValue().'%' 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Filters/Types/Like.php: -------------------------------------------------------------------------------- 1 | getHttpValue().'%'; 17 | 18 | if (InstalledVersions::satisfies(new VersionParser, 'laravel/framework', '>11.17.0')) { 19 | return $builder->whereLike($this->column, $value); 20 | } 21 | 22 | /** 23 | * @deprecated logic for older Laravel versions 24 | */ 25 | return $builder->where($this->column, 'like', $value); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Filters/Types/Where.php: -------------------------------------------------------------------------------- 1 | where($this->column, $this->getHttpValue()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Filters/Types/WhereBetween.php: -------------------------------------------------------------------------------- 1 | whereBetween($this->column, $this->getHttpValue()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Filters/Types/WhereDate.php: -------------------------------------------------------------------------------- 1 | whereDate($this->column, $this->getHttpValue()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Filters/Types/WhereDateStartEnd.php: -------------------------------------------------------------------------------- 1 | getHttpValue(); 15 | 16 | $builder->when($value['start'] ?? null, fn (Builder $query) => $query->whereDate($this->column, '>=', $value['start'])); 17 | $builder->when($value['end'] ?? null, fn (Builder $query) => $query->whereDate($this->column, '<=', $value['end'])); 18 | 19 | return $builder; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Filters/Types/WhereIn.php: -------------------------------------------------------------------------------- 1 | getHttpValue(); 16 | 17 | $value = is_array($query) ? $query : Str::of($query)->explode(','); 18 | 19 | return $builder->whereIn($this->column, $value); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Filters/Types/WhereMaxMin.php: -------------------------------------------------------------------------------- 1 | getHttpValue(); 15 | 16 | $builder->when($value['min'] ?? null, fn (Builder $query) => $query->where($this->column, '>=', $value['min'])); 17 | $builder->when($value['max'] ?? null, fn (Builder $query) => $query->where($this->column, '<=', $value['max'])); 18 | 19 | return $builder; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Platform/Commands/ChartCommand.php: -------------------------------------------------------------------------------- 1 | resolveStubPath('chart.stub'); 39 | } 40 | 41 | /** 42 | * Get the default namespace for the class. 43 | * 44 | * @param string $rootNamespace 45 | */ 46 | protected function getDefaultNamespace($rootNamespace): string 47 | { 48 | return $rootNamespace.'\Orchid\Layouts'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Commands/FilterCommand.php: -------------------------------------------------------------------------------- 1 | resolveStubPath('filters.stub'); 39 | } 40 | 41 | /** 42 | * Get the default namespace for the class. 43 | * 44 | * @param string $rootNamespace 45 | */ 46 | protected function getDefaultNamespace($rootNamespace): string 47 | { 48 | return $rootNamespace.'\Orchid\Filters'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Commands/GeneratorCommand.php: -------------------------------------------------------------------------------- 1 | laravel->basePath('stubs/orchid/platform/'.trim($stub, '/')); 19 | 20 | return file_exists($path) 21 | ? $path 22 | : Dashboard::path('stubs/'.$stub); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Platform/Commands/ListenerCommand.php: -------------------------------------------------------------------------------- 1 | resolveStubPath('listener.stub'); 39 | } 40 | 41 | /** 42 | * Get the default namespace for the class. 43 | * 44 | * @param string $rootNamespace 45 | */ 46 | protected function getDefaultNamespace($rootNamespace): string 47 | { 48 | return $rootNamespace.'\Orchid\Layouts'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Commands/PresenterCommand.php: -------------------------------------------------------------------------------- 1 | resolveStubPath('presenter.stub'); 39 | } 40 | 41 | /** 42 | * Get the default namespace for the class. 43 | * 44 | * @param string $rootNamespace 45 | */ 46 | protected function getDefaultNamespace($rootNamespace): string 47 | { 48 | return $rootNamespace.'\Orchid\Presenters'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Commands/PublishCommand.php: -------------------------------------------------------------------------------- 1 | call('vendor:publish', [ 35 | '--tag' => 'orchid-assets', 36 | '--force' => true, 37 | ]); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Platform/Commands/RowsCommand.php: -------------------------------------------------------------------------------- 1 | resolveStubPath('rows.stub'); 39 | } 40 | 41 | /** 42 | * Get the default namespace for the class. 43 | * 44 | * @param string $rootNamespace 45 | */ 46 | protected function getDefaultNamespace($rootNamespace): string 47 | { 48 | return $rootNamespace.'\Orchid\Layouts'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Commands/ScreenCommand.php: -------------------------------------------------------------------------------- 1 | resolveStubPath('screen.stub'); 39 | } 40 | 41 | /** 42 | * Get the default namespace for the class. 43 | * 44 | * @param string $rootNamespace 45 | */ 46 | protected function getDefaultNamespace($rootNamespace): string 47 | { 48 | return $rootNamespace.'\Orchid\Screens'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Commands/SelectionCommand.php: -------------------------------------------------------------------------------- 1 | resolveStubPath('selection.stub'); 39 | } 40 | 41 | /** 42 | * Get the default namespace for the class. 43 | * 44 | * @param string $rootNamespace 45 | */ 46 | protected function getDefaultNamespace($rootNamespace): string 47 | { 48 | return $rootNamespace.'\Orchid\Layouts'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Commands/TabMenuCommand.php: -------------------------------------------------------------------------------- 1 | resolveStubPath('tabMenu.stub'); 39 | } 40 | 41 | /** 42 | * Get the default namespace for the class. 43 | * 44 | * @param string $rootNamespace 45 | */ 46 | protected function getDefaultNamespace($rootNamespace): string 47 | { 48 | return $rootNamespace.'\Orchid\Layouts'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Commands/TableCommand.php: -------------------------------------------------------------------------------- 1 | resolveStubPath('table.stub'); 39 | } 40 | 41 | /** 42 | * Get the default namespace for the class. 43 | * 44 | * @param string $rootNamespace 45 | */ 46 | protected function getDefaultNamespace($rootNamespace): string 47 | { 48 | return $rootNamespace.'\Orchid\Layouts'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Components/Notification.php: -------------------------------------------------------------------------------- 1 | user = $guard->user(); 25 | } 26 | 27 | /** 28 | * Get the view / contents that represent the component. 29 | * 30 | * @return View|string 31 | */ 32 | public function render() 33 | { 34 | $notifications = $this->user 35 | ->unreadNotifications() 36 | ->where('type', DashboardMessage::class) 37 | ->limit(15) 38 | ->get(); 39 | 40 | return view('platform::components.notification', [ 41 | 'notifications' => $notifications, 42 | ]); 43 | } 44 | 45 | /** 46 | * Determine if the component should be rendered. 47 | * 48 | * @return bool 49 | */ 50 | public function shouldRender(): bool 51 | { 52 | return config('platform.notifications.enabled', true); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Platform/Components/Stream.php: -------------------------------------------------------------------------------- 1 | {$this->getSortColumnName()}; 27 | } 28 | 29 | /** 30 | * Set the sort column value. 31 | * 32 | * @param int $sortOrder The new sort column value. 33 | * 34 | * @return $this 35 | */ 36 | public function setSortColumn(int $sortOrder): static 37 | { 38 | $this->{$this->getSortColumnName()} = $sortOrder; 39 | 40 | return $this; 41 | } 42 | 43 | /** 44 | * Scope a query to sort the results by the sort column. 45 | * 46 | * @param \Illuminate\Database\Eloquent\Builder $query 47 | * @param string $direction The sorting direction (ASC or DESC). Default is ASC. 48 | * 49 | * @return \Illuminate\Database\Eloquent\Builder 50 | */ 51 | public function scopeSorted($query, $direction = 'ASC') 52 | { 53 | $column = $this->getSortColumnName(); 54 | 55 | return $query->orderBy($column, $direction); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Platform/Configuration/ManagesModelOptions.php: -------------------------------------------------------------------------------- 1 | model($key, $default); 22 | 23 | return class_exists($model) ? new $model : $model; 24 | } 25 | 26 | /** 27 | * Get the class name for a given Dashboard model. 28 | */ 29 | public function model(string $key, ?string $default = null): string 30 | { 31 | return Arr::get($this->registeredReplaceModels, $key, $default ?? $key); 32 | } 33 | 34 | /** 35 | * Get the user model class name. 36 | */ 37 | public function useModel(string $key, string $custom): static 38 | { 39 | $this->registeredReplaceModels[$key] = $custom; 40 | 41 | return $this; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Platform/Configuration/ManagesPackage.php: -------------------------------------------------------------------------------- 1 | > 13 | */ 14 | protected static array $registeredSearchModels = []; 15 | 16 | /** 17 | * Registers a set of models for which full-text search is required. 18 | * 19 | * @param array $models 20 | * 21 | * @return static 22 | */ 23 | public function registerSearch(array $models): static 24 | { 25 | static::$registeredSearchModels = array_merge(static::$registeredSearchModels, $models); 26 | 27 | return $this; 28 | } 29 | 30 | /** 31 | * Get the list of searchable models, ensuring uniqueness and resolving model instances. 32 | * 33 | * @return Collection The collection of searchable models. 34 | */ 35 | public function getSearch(): Collection 36 | { 37 | return collect(static::$registeredSearchModels) 38 | ->unique() 39 | ->transform(static fn ($model) => is_object($model) ? $model : resolve($model)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Platform/Events/AddRoleEvent.php: -------------------------------------------------------------------------------- 1 | roles = collect($role); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Platform/Events/InstallEvent.php: -------------------------------------------------------------------------------- 1 | roles = collect($role); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Platform/Events/ReplicateFileEvent.php: -------------------------------------------------------------------------------- 1 | middleware(static function ($request, $next) use ($permission) { 33 | if (Auth::user()->hasAccess($permission)) { 34 | return $next($request); 35 | } 36 | abort(403); 37 | }); 38 | 39 | abort_if(Auth::user() !== null && ! Auth::user()->hasAccess($permission), 403); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Platform/Http/Controllers/IndexController.php: -------------------------------------------------------------------------------- 1 | route(config('platform.index')); 21 | } 22 | 23 | /** 24 | * Show the fallback view for undefined routes. 25 | */ 26 | public function fallback(): View 27 | { 28 | return view('platform::errors.404'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Platform/Http/Controllers/SortableController.php: -------------------------------------------------------------------------------- 1 | input('model'); 19 | 20 | abort_unless(class_exists($classModel), 400); 21 | 22 | $model = new $classModel; 23 | 24 | $request->collect('items')->each(function ($item) use ($model) { 25 | $model->where($model->getKeyName(), '=', $item['id'])->update([ 26 | $model->getSortColumnName() => $item['sortOrder'], 27 | ]); 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Platform/Http/Layouts/NotificationTable.php: -------------------------------------------------------------------------------- 1 | cantHide() 27 | ->render(static fn ($notification) => view('platform::partials.notification', [ 28 | 'notification' => $notification, 29 | ])), 30 | ]; 31 | } 32 | 33 | public function textNotFound(): string 34 | { 35 | return __('No notifications'); 36 | } 37 | 38 | public function iconNotFound(): string 39 | { 40 | return 'bs.bell'; 41 | } 42 | 43 | public function subNotFound(): string 44 | { 45 | return __('You currently have no notifications, but maybe they will appear later.'); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Platform/Http/Layouts/SearchLayout.php: -------------------------------------------------------------------------------- 1 | isNotEmpty(); 20 | } 21 | 22 | /** 23 | * @throws Throwable 24 | */ 25 | public function fields(): array 26 | { 27 | $searchModel = $this->query->get('model'); 28 | 29 | $layouts = Dashboard::getSearch() 30 | ->map(static function (Model $model) use ($searchModel) { 31 | $radio = Radio::make('type') 32 | ->value(get_class($model)) 33 | ->horizontal() 34 | ->clear() 35 | ->placeholder($model->presenter()->label()); 36 | 37 | if ($model instanceof $searchModel) { 38 | $radio->checked(); 39 | } 40 | 41 | return $radio; 42 | }); 43 | 44 | $layouts->prepend(Label::make('search')->clear()->title(__('Choose record type:'))); 45 | 46 | return [ 47 | Group::make($layouts->all())->autoWidth(), 48 | ]; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Platform/Http/Middleware/BladeIcons.php: -------------------------------------------------------------------------------- 1 | iconFinder->setSize('1.25em', '1.25em'); 20 | 21 | return $next($request); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Platform/Http/Requests/RelationRequest.php: -------------------------------------------------------------------------------- 1 | 'string|nullable', 20 | 'model' => 'string|required', 21 | 'key' => 'string|required', 22 | 'name' => 'string|required', 23 | 'scope' => 'string|nullable', 24 | 'append' => 'nullable', 25 | 'searchColumns' => 'string|nullable', 26 | ]; 27 | } 28 | 29 | /** 30 | * Prepare the data for validation. 31 | * 32 | * @return void 33 | */ 34 | protected function prepareForValidation() 35 | { 36 | $this->merge([ 37 | 'append' => $this->append, 38 | 'searchColumns' => $this->searchColumns, 39 | ]); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Platform/ItemPermission.php: -------------------------------------------------------------------------------- 1 | group = $group; 38 | 39 | return $item; 40 | } 41 | 42 | /** 43 | * Add a permission to the permission group. 44 | * 45 | * @param string $slug The slug of the permission. 46 | * @param string $name The description of the permission. 47 | * 48 | * @return $this The current permission group instance. 49 | */ 50 | public function addPermission(string $slug, string $name): self 51 | { 52 | $this->items[] = [ 53 | 'slug' => $slug, 54 | 'description' => $name, 55 | ]; 56 | 57 | return $this; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Platform/Models/Role.php: -------------------------------------------------------------------------------- 1 | 'array', 41 | ]; 42 | 43 | /** 44 | * @var array 45 | */ 46 | protected $allowedFilters = [ 47 | 'id' => Where::class, 48 | 'name' => Like::class, 49 | 'slug' => Like::class, 50 | 'permissions' => Like::class, 51 | ]; 52 | 53 | /** 54 | * @var array 55 | */ 56 | protected $allowedSorts = [ 57 | 'id', 58 | 'name', 59 | 'slug', 60 | 'updated_at', 61 | 'created_at', 62 | ]; 63 | } 64 | -------------------------------------------------------------------------------- /src/Screen/Actions/DropDown.php: -------------------------------------------------------------------------------- 1 | 'btn btn-link icon-link gap-2', 33 | 'source' => null, 34 | 'icon' => null, 35 | 'list' => [], 36 | ]; 37 | 38 | /** 39 | * @param Actionable[] $list 40 | */ 41 | public function list(array $list): self 42 | { 43 | return $this->set('list', $list); 44 | } 45 | 46 | /** 47 | * @throws \Throwable 48 | * 49 | * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|mixed 50 | */ 51 | public function build(?Repository $repository = null) 52 | { 53 | $this->set('source', $repository); 54 | 55 | return $this->render(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Screen/Actions/Toggle.php: -------------------------------------------------------------------------------- 1 | 'form-check-input', 32 | 'type' => 'checkbox', 33 | 'novalidate' => false, 34 | 'method' => null, 35 | 'icon' => null, 36 | 'action' => null, 37 | 'confirm' => null, 38 | 'parameters' => [], 39 | 'turbo' => true, 40 | 'form' => 'post-form', 41 | 'status' => false, 42 | ]; 43 | 44 | public function __construct() 45 | { 46 | parent::__construct(); 47 | 48 | $this->addBeforeRender(function () { 49 | $this->set('placeholder', $this->get('title')); 50 | $this->set('title', null); 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Screen/AsMultiSource.php: -------------------------------------------------------------------------------- 1 | getBaseContent($field) ?? $this->getContentMultiLang($field, $locale); 29 | } 30 | 31 | /** 32 | * @param null $locale 33 | * 34 | * @return mixed 35 | */ 36 | private function getContentMultiLang(string $field, $locale = null) 37 | { 38 | $jsonContent = (array) $this->getAttribute($this->jsonColumnName); 39 | $fullName = ($locale ?? app()->getLocale()).'.'.$field; 40 | if (Arr::has($jsonContent, $fullName)) { 41 | return Arr::get($jsonContent, $fullName); 42 | } 43 | 44 | return Arr::get($jsonContent, config('app.fallback_locale').'.'.$field); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Screen/AsSource.php: -------------------------------------------------------------------------------- 1 | getAttribute($field); 31 | } 32 | 33 | return $this->getAttribute($field) // Try to get the field value from the object's attributes. 34 | ?? Arr::get($this->getRelations(), $field) // Try to get the field value from the object's relations. 35 | ?? Arr::get($this->attributesToArray(), $field); // Try to get the field value from the object's array representation. 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Screen/CanSee.php: -------------------------------------------------------------------------------- 1 | display = $value; 37 | 38 | return $this; 39 | } 40 | 41 | /** 42 | * Check if the element is visible. 43 | * 44 | * This method returns the current visibility status of the component. 45 | * 46 | * @return bool `true` if the element is visible, `false` if it is hidden. 47 | */ 48 | public function isSee(): bool 49 | { 50 | return $this->display; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Screen/Commander.php: -------------------------------------------------------------------------------- 1 | commandBar()) 22 | ->map(static fn (Actionable $command) => $command->build($repository)) 23 | ->filter() 24 | ->all(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Screen/Components/Cells/Boolean.php: -------------------------------------------------------------------------------- 1 | value = $value; 26 | $this->true = $true; 27 | $this->false = $false; 28 | } 29 | 30 | /** 31 | * Get the view/contents that represent the component. 32 | * 33 | * @return \Illuminate\Contracts\View\View|\Closure|string 34 | */ 35 | public function render() 36 | { 37 | $class = 'me-1 '.($this->value ? 'text-success' : 'text-danger'); 38 | $label = $this->value ? $this->true : $this->false; 39 | 40 | return "".$label; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Screen/Components/Cells/Currency.php: -------------------------------------------------------------------------------- 1 | value, $this->decimals, $this->decimal_separator, $this->thousands_separator); 37 | 38 | return Str::of($value) 39 | ->prepend($this->before.' ') 40 | ->append(' '.$this->after) 41 | ->trim() 42 | ->toString(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Screen/Components/Cells/DateTime.php: -------------------------------------------------------------------------------- 1 | value, $this->tz)->translatedFormat($this->format); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Screen/Components/Cells/DateTimeSplit.php: -------------------------------------------------------------------------------- 1 | value, $this->tz); 34 | 35 | return sprintf('', 36 | $date->translatedFormat($this->upperFormat), 37 | $date->translatedFormat($this->lowerFormat), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Screen/Components/Cells/Number.php: -------------------------------------------------------------------------------- 1 | value, $this->decimals, $this->decimal_separator, $this->thousands_separator); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Screen/Components/Cells/Percentage.php: -------------------------------------------------------------------------------- 1 | value * 100, $this->decimals, $this->decimal_separator, $this->thousands_separator).'%'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Screen/Components/Cells/Text.php: -------------------------------------------------------------------------------- 1 | 36 | @empty(!$title){{ $title }}@endempty 37 | {{ $text }}', [ 38 | 'class' => $this->clamp ? 'line-clamp-'.$this->clamp : '', 39 | 'title' => $this->title ? Str::of($this->value->getContent($this->title))->words($this->words) : '', 40 | 'text' => Str::of($this->value->getContent($this->text))->words($this->words), 41 | ]); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Screen/Components/Cells/Time.php: -------------------------------------------------------------------------------- 1 | value, $this->tz)->toTimeString($this->unitPrecision); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Screen/Components/Popover.php: -------------------------------------------------------------------------------- 1 | content = $content; 32 | $this->placement = $placement; 33 | } 34 | 35 | /** 36 | * Get the view / contents that represent the component. 37 | * 38 | * @return View|string 39 | */ 40 | public function render() 41 | { 42 | return view('platform::components.popover'); 43 | } 44 | 45 | /** 46 | * Determine if the component should be rendered. 47 | * 48 | * @return bool 49 | */ 50 | public function shouldRender() 51 | { 52 | return ! empty($this->content); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Screen/Concerns/ComplexFieldConcern.php: -------------------------------------------------------------------------------- 1 | name($name); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Screen/Concerns/Multipliable.php: -------------------------------------------------------------------------------- 1 | set('multiple', 'multiple'); 17 | $this->set('allowEmpty', '1'); // TODO do NOT allow null value when multiple is on 18 | 19 | $this->inlineAttributes[] = 'multiple'; 20 | 21 | return $this->addBeforeRender(function () { 22 | $name = $this->get('name'); 23 | 24 | $this->set('name', Str::finish($name, '[]')); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Screen/Contracts/Actionable.php: -------------------------------------------------------------------------------- 1 | message = 'Field must have the following attribute: '.$attribute; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Screen/Fields/Label.php: -------------------------------------------------------------------------------- 1 | null, 30 | 'value' => null, 31 | ]; 32 | 33 | /** 34 | * Attributes available for a particular tag. 35 | * 36 | * @var array 37 | */ 38 | protected $inlineAttributes = [ 39 | 'class', 40 | ]; 41 | } 42 | -------------------------------------------------------------------------------- /src/Screen/Fields/Map.php: -------------------------------------------------------------------------------- 1 | 14, 35 | 'height' => '300px', 36 | ]; 37 | 38 | /** 39 | * Attributes available for a particular tag. 40 | * 41 | * @var array 42 | */ 43 | protected $inlineAttributes = [ 44 | 'name', 45 | 'required', 46 | 'height', 47 | ]; 48 | } 49 | -------------------------------------------------------------------------------- /src/Screen/Fields/NumberRange.php: -------------------------------------------------------------------------------- 1 | 'form-control', 28 | 'type' => 'number', 29 | ]; 30 | /** 31 | * Attributes available for a particular tag. 32 | * 33 | * @var array 34 | */ 35 | protected $inlineAttributes = [ 36 | 'form', 37 | 'name', 38 | 'class', 39 | 'min', 40 | 'max', 41 | 'pattern', 42 | 'readonly', 43 | 'step', 44 | 'type', 45 | ]; 46 | } 47 | -------------------------------------------------------------------------------- /src/Screen/Fields/Range.php: -------------------------------------------------------------------------------- 1 | view = $view; 20 | 21 | return $this; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Blank.php: -------------------------------------------------------------------------------- 1 | layouts = $layouts; 28 | } 29 | 30 | /** 31 | * @return \Illuminate\View\View|mixed 32 | */ 33 | public function build(Repository $repository) 34 | { 35 | return $this->buildAsDeep($repository); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Card.php: -------------------------------------------------------------------------------- 1 | commandBar = $commandBar; 35 | } 36 | 37 | public function render(Cardable $card): View 38 | { 39 | return view($this->template, [ 40 | 'title' => $card->title(), 41 | 'description' => $card->description(), 42 | 'image' => $card->image(), 43 | 'commandBar' => $this->buildCommandBar(), 44 | 'color' => $card->color()?->name(), 45 | ]); 46 | } 47 | 48 | private function buildCommandBar(): array 49 | { 50 | return collect($this->commandBar) 51 | ->map(fn (Actionable $command) => $command->build($this->query))->all(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Columns.php: -------------------------------------------------------------------------------- 1 | layouts = $layouts; 28 | } 29 | 30 | /** 31 | * @return mixed 32 | */ 33 | public function build(Repository $repository) 34 | { 35 | return $this->buildAsDeep($repository); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Component.php: -------------------------------------------------------------------------------- 1 | component = $component; 29 | } 30 | 31 | /** 32 | * @throws \Illuminate\Contracts\Container\BindingResolutionException 33 | * 34 | * @return mixed 35 | */ 36 | public function build(Repository $repository) 37 | { 38 | $this->query = $repository; 39 | 40 | if (! $this->isSee()) { 41 | return; 42 | } 43 | 44 | $data = array_merge($repository->toArray(), $this->data); 45 | 46 | $component = Blade::resolveComponent($this->component, $data); 47 | 48 | if (! $component->shouldRender()) { 49 | return; 50 | } 51 | 52 | $resolve = $component->resolveView(); 53 | 54 | $view = is_string($resolve) ? view($resolve) : $resolve; 55 | 56 | return $view->with($component->data()); 57 | } 58 | 59 | public function with(array $data): self 60 | { 61 | $this->data = array_merge($this->data, $data); 62 | 63 | return $this; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Content.php: -------------------------------------------------------------------------------- 1 | target = $target; 32 | } 33 | 34 | public function build(Repository $repository): string 35 | { 36 | $this->query = $repository; 37 | 38 | if (is_string($this->target) || is_array($this->target)) { 39 | $this->target = $repository->get($this->target, $this->target); 40 | } 41 | 42 | return (string) $this; 43 | } 44 | 45 | public function __toString(): string 46 | { 47 | if (method_exists($this, 'render')) { 48 | return (string) $this->render($this->target); 49 | } 50 | 51 | throw new \RuntimeException('Method render not found'); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Facepile.php: -------------------------------------------------------------------------------- 1 | template, [ 24 | 'users' => $users, 25 | ]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Metric.php: -------------------------------------------------------------------------------- 1 | labels = $labels; 34 | } 35 | 36 | /** 37 | * @return Factory|\Illuminate\View\View 38 | */ 39 | public function build(Repository $repository) 40 | { 41 | $this->query = $repository; 42 | 43 | if (! $this->isSee() || empty($this->labels)) { 44 | return; 45 | } 46 | 47 | $metrics = collect($this->labels)->map(fn (string $value) => $repository->getContent($value, '')); 48 | 49 | return view($this->template, [ 50 | 'title' => $this->title, 51 | 'metrics' => $metrics, 52 | ]); 53 | } 54 | 55 | /** 56 | * @return $this 57 | */ 58 | public function title(string $title): Metric 59 | { 60 | $this->title = $title; 61 | 62 | return $this; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Persona.php: -------------------------------------------------------------------------------- 1 | template, [ 20 | 'title' => $user->title(), 21 | 'subTitle' => $user->subTitle(), 22 | 'image' => $user->image(), 23 | 'url' => $user->url(), 24 | ]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Rows.php: -------------------------------------------------------------------------------- 1 | query = $repository; 44 | 45 | if (! $this->isSee()) { 46 | return; 47 | } 48 | 49 | $form = new Builder($this->fields(), $repository); 50 | 51 | return view($this->template, [ 52 | 'form' => $form->generateForm(), 53 | 'title' => $this->title, 54 | ]); 55 | } 56 | 57 | public function title(?string $title = null): self 58 | { 59 | $this->title = $title; 60 | 61 | return $this; 62 | } 63 | 64 | /** 65 | * @return iterable|iterable 66 | */ 67 | abstract protected function fields(): iterable; 68 | } 69 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Selection.php: -------------------------------------------------------------------------------- 1 | query = $repository; 38 | 39 | if (! $this->isSee()) { 40 | return; 41 | } 42 | 43 | $filters = collect($this->filters()) 44 | ->map(static fn ($filter) => is_string($filter) ? resolve($filter) : $filter) 45 | ->filter(fn (Filter $filter) => $filter->isDisplay()); 46 | 47 | if ($filters->isEmpty()) { 48 | return; 49 | } 50 | 51 | return view($this->template, [ 52 | 'filters' => $filters, 53 | 'chunk' => ceil($filters->count() / 4), 54 | ]); 55 | } 56 | 57 | /** 58 | * @return Filter[] 59 | */ 60 | abstract public function filters(): iterable; 61 | } 62 | -------------------------------------------------------------------------------- /src/Screen/Layouts/TabMenu.php: -------------------------------------------------------------------------------- 1 | query = $repository; 32 | 33 | if (! $this->isSee()) { 34 | return; 35 | } 36 | 37 | $form = new Builder($this->navigations(), $repository); 38 | 39 | return view($this->template, [ 40 | 'navigations' => $form->generateForm(), 41 | ]); 42 | } 43 | 44 | /** 45 | * Get the menu elements to be displayed. 46 | * 47 | * @return Menu[] 48 | */ 49 | abstract protected function navigations(): iterable; 50 | } 51 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Tabs.php: -------------------------------------------------------------------------------- 1 | null, 25 | ]; 26 | 27 | /** 28 | * Layout constructor. 29 | * 30 | * @param Layout[] $layouts 31 | */ 32 | public function __construct(array $layouts = []) 33 | { 34 | $this->layouts = $layouts; 35 | } 36 | 37 | /** 38 | * @return mixed 39 | */ 40 | public function build(Repository $repository) 41 | { 42 | return $this->buildAsDeep($repository); 43 | } 44 | 45 | /** 46 | * @return $this 47 | */ 48 | public function activeTab(string $name) 49 | { 50 | $this->variables['activeTab'] = $name; 51 | 52 | return $this; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Screen/Layouts/View.php: -------------------------------------------------------------------------------- 1 | template = $template; 28 | $this->data = $data; 29 | } 30 | 31 | /** 32 | * @return mixed 33 | */ 34 | public function build(Repository $repository) 35 | { 36 | $this->query = $repository; 37 | 38 | if (! $this->isSee()) { 39 | return; 40 | } 41 | 42 | $data = array_merge($this->data, $repository->toArray()); 43 | 44 | return view($this->template, $data); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Screen/Layouts/Wrapper.php: -------------------------------------------------------------------------------- 1 | template = $template; 24 | $this->layouts = $layouts; 25 | } 26 | 27 | /** 28 | * @return \Illuminate\Contracts\View\View|void 29 | */ 30 | public function build(Repository $repository) 31 | { 32 | $this->query = $repository; 33 | 34 | if (! $this->isSee()) { 35 | return; 36 | } 37 | 38 | $build = collect($this->layouts) 39 | ->map(function ($layout, $key) use ($repository) { 40 | $items = $this->buildChild(Arr::wrap($layout), $key, $repository); 41 | 42 | return ! is_array($layout) ? reset($items)[0] : reset($items); 43 | }) 44 | ->merge($repository->all()) 45 | ->all(); 46 | 47 | return view($this->template, $build); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Screen/Repository.php: -------------------------------------------------------------------------------- 1 | items = collect($items)->all(); 29 | } 30 | 31 | /** 32 | * @param mixed|null $default 33 | * 34 | * @return mixed 35 | */ 36 | public function getContent(string $key, $default = null) 37 | { 38 | return Arr::get($this->items, $key, $default); 39 | } 40 | 41 | public function toArray(): array 42 | { 43 | return $this->items; 44 | } 45 | 46 | public function count(): int 47 | { 48 | return count($this->items); 49 | } 50 | 51 | /** 52 | * @param $key 53 | * @param $value 54 | * 55 | * @return $this 56 | */ 57 | public function set($key, $value = null): self 58 | { 59 | parent::set($key, $value); 60 | 61 | return $this; 62 | } 63 | 64 | /** 65 | * @return bool 66 | */ 67 | public function isEmpty(): bool 68 | { 69 | return $this->count() === 0; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Screen/Sight.php: -------------------------------------------------------------------------------- 1 | $this->column, 22 | 'title' => $this->title, 23 | 'popover' => $this->popover, 24 | ]); 25 | } 26 | 27 | /** 28 | * Builds content for the column. 29 | * 30 | * @param Repository|Model $repository 31 | * 32 | * @return string|\Illuminate\Contracts\Support\Htmlable|null 33 | */ 34 | public function buildDd($repository) 35 | { 36 | $value = $this->render 37 | ? $this->handler($repository) 38 | : $repository->getContent($this->name); 39 | 40 | return $this->render === null 41 | ? e($value) 42 | : $value; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Support/Assert.php: -------------------------------------------------------------------------------- 1 | all(); 34 | } 35 | 36 | if (! is_array($array)) { 37 | return false; 38 | } 39 | 40 | return count($array) === count(array_filter($array, $callback)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Support/Attributes/FlushOctaneState.php: -------------------------------------------------------------------------------- 1 | toDateTimeString(); 21 | } 22 | 23 | /** 24 | * Format bytes to KB, MB, GB, TB. 25 | */ 26 | public static function formatBytes(int $size, int $precision = 2): string 27 | { 28 | if ($size <= 0) { 29 | return (string) $size; 30 | } 31 | 32 | $base = log($size) / log(1024); 33 | $suffixes = [' bytes', ' KB', ' MB', ' GB', ' TB']; 34 | 35 | return round(1024 ** ($base - floor($base)), $precision).$suffixes[(int) floor($base)]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Support/Names.php: -------------------------------------------------------------------------------- 1 | replace('.', $separator)->slug() 31 | : $prefix; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Support/Testing/MakesHttpRequestsWrapper.php: -------------------------------------------------------------------------------- 1 | app; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Support/Testing/ScreenTesting.php: -------------------------------------------------------------------------------- 1 | parameters($parameters); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /stubs/app/Orchid/Layouts/Examples/ChartBarExample.php: -------------------------------------------------------------------------------- 1 | 1, 25 | 'regionFill' => 1, 26 | 'hideDots' => 0, 27 | 'hideLine' => 0, 28 | 'heatline' => 0, 29 | 'dotSize' => 3, 30 | ]; 31 | 32 | /** 33 | * To highlight certain values on the Y axis, markers can be set. 34 | * They will shown as dashed lines on the graph. 35 | */ 36 | protected function markers(): ?array 37 | { 38 | return [ 39 | [ 40 | 'label' => 'Medium', 41 | 'value' => 40, 42 | ], 43 | ]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /stubs/app/Orchid/Layouts/Examples/ChartPercentageExample.php: -------------------------------------------------------------------------------- 1 | route('platform.example.fields'), 20 | 21 | Menu::make('Advanced Elements') 22 | ->route('platform.example.advanced'), 23 | 24 | Menu::make('Text Editors') 25 | ->route('platform.example.editors'), 26 | 27 | Menu::make('Run Actions') 28 | ->route('platform.example.actions'), 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /stubs/app/Orchid/Layouts/Examples/TabMenuExample.php: -------------------------------------------------------------------------------- 1 | route('platform.example.layouts'), 20 | 21 | Menu::make('Get Started') 22 | ->route('platform.main'), 23 | 24 | Menu::make('Documentation') 25 | ->url('https://orchid.software/en/docs'), 26 | 27 | Menu::make('Example Screen') 28 | ->route('platform.example') 29 | ->badge(fn () => 6), 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /stubs/app/Orchid/Layouts/Role/RoleEditLayout.php: -------------------------------------------------------------------------------- 1 | type('text') 23 | ->max(255) 24 | ->required() 25 | ->title(__('Name')) 26 | ->placeholder(__('Name')) 27 | ->help(__('Role display name')), 28 | 29 | Input::make('role.slug') 30 | ->type('text') 31 | ->max(255) 32 | ->required() 33 | ->title(__('Slug')) 34 | ->placeholder(__('Slug')) 35 | ->help(__('Actual name in the system')), 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /stubs/app/Orchid/Layouts/Role/RoleListLayout.php: -------------------------------------------------------------------------------- 1 | sort() 29 | ->cantHide() 30 | ->filter(Input::make()) 31 | ->render(fn (Role $role) => Link::make($role->name) 32 | ->route('platform.systems.roles.edit', $role->id)), 33 | 34 | TD::make('slug', __('Slug')) 35 | ->sort() 36 | ->cantHide() 37 | ->filter(Input::make()), 38 | 39 | TD::make('created_at', __('Created')) 40 | ->usingComponent(DateTimeSplit::class) 41 | ->align(TD::ALIGN_RIGHT) 42 | ->defaultHidden() 43 | ->sort(), 44 | 45 | TD::make('updated_at', __('Last edit')) 46 | ->usingComponent(DateTimeSplit::class) 47 | ->align(TD::ALIGN_RIGHT) 48 | ->sort(), 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /stubs/app/Orchid/Layouts/User/ProfilePasswordLayout.php: -------------------------------------------------------------------------------- 1 | placeholder(__('Enter the current password')) 23 | ->title(__('Current password')) 24 | ->help('This is your password set at the moment.'), 25 | 26 | Password::make('password') 27 | ->placeholder(__('Enter the password to be set')) 28 | ->title(__('New password')), 29 | 30 | Password::make('password_confirmation') 31 | ->placeholder(__('Enter the password to be set')) 32 | ->title(__('Confirm new password')) 33 | ->help('A good password is at least 15 characters or at least 8 characters long, including a number and a lowercase letter.'), 34 | ]; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /stubs/app/Orchid/Layouts/User/UserEditLayout.php: -------------------------------------------------------------------------------- 1 | type('text') 23 | ->max(255) 24 | ->required() 25 | ->title(__('Name')) 26 | ->placeholder(__('Name')), 27 | 28 | Input::make('user.email') 29 | ->type('email') 30 | ->required() 31 | ->title(__('Email')) 32 | ->placeholder(__('Email')), 33 | ]; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /stubs/app/Orchid/Layouts/User/UserFiltersLayout.php: -------------------------------------------------------------------------------- 1 | query->get('user'); 23 | 24 | $exists = $user->exists; 25 | 26 | $placeholder = $exists 27 | ? __('Leave empty to keep current password') 28 | : __('Enter the password to be set'); 29 | 30 | return [ 31 | Password::make('user.password') 32 | ->placeholder($placeholder) 33 | ->title(__('Password')) 34 | ->required(! $exists), 35 | ]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /stubs/app/Orchid/Layouts/User/UserRoleLayout.php: -------------------------------------------------------------------------------- 1 | fromModel(Role::class, 'name') 24 | ->multiple() 25 | ->title(__('Name role')) 26 | ->help('Specify which groups this account should belong to'), 27 | ]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /stubs/app/Orchid/Screens/PlatformScreen.php: -------------------------------------------------------------------------------- 1 | 3 | merge([ 6 | 'data-{{ controller }}-target' => 'name', 7 | 'data-action' => 'input->{{ controller }}#greet', 8 | ]) 9 | }}> 10 | 11 | 12 | 13 | @endcomponent 14 | 15 | 29 | -------------------------------------------------------------------------------- /stubs/field.stub: -------------------------------------------------------------------------------- 1 | 'Enter text...', 23 | 'class' => 'form-control', 24 | 'type' => 'text', 25 | ]; 26 | 27 | /** 28 | * List of attributes available for the HTML tag. 29 | * 30 | * @var array 31 | */ 32 | protected $inlineAttributes = [ 33 | 'placeholder', 34 | 'value', 35 | 'type', 36 | 'name' 37 | ]; 38 | } 39 | -------------------------------------------------------------------------------- /stubs/filters.stub: -------------------------------------------------------------------------------- 1 | route(config('platform.index')), 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /stubs/table.stub: -------------------------------------------------------------------------------- 1 |