diff --git a/ProcessMaker/Http/Controllers/Api/DevLinkController.php b/ProcessMaker/Http/Controllers/Api/DevLinkController.php index 634ddac124..e77f926d3e 100644 --- a/ProcessMaker/Http/Controllers/Api/DevLinkController.php +++ b/ProcessMaker/Http/Controllers/Api/DevLinkController.php @@ -4,12 +4,13 @@ use Illuminate\Http\Request; use Illuminate\Validation\Rule; +use ProcessMaker\Exception\ValidationException; use ProcessMaker\Http\Controllers\Controller; use ProcessMaker\Http\Resources\ApiCollection; use ProcessMaker\Jobs\DevLinkInstall; -use ProcessMaker\Exception\ValidationException; use ProcessMaker\Models\Bundle; use ProcessMaker\Models\BundleAsset; +use ProcessMaker\Models\BundleSetting; use ProcessMaker\Models\DevLink; use ProcessMaker\Models\Setting; @@ -119,7 +120,7 @@ public function localBundles(Request $request) public function showBundle(Bundle $bundle) { - return $bundle->load('assets'); + return $bundle->load('assets')->load('settings'); } public function remoteBundles(Request $request, DevLink $devLink) @@ -131,6 +132,7 @@ public function createBundle(Request $request) { $bundle = new Bundle(); $bundle->name = $request->input('name'); + $bundle->description = $request->input('description'); $bundle->published = (bool) $request->input('published', false); $bundle->version = 1; $bundle->saveOrFail(); @@ -143,6 +145,7 @@ public function updateBundle(Request $request, Bundle $bundle) $bundle->validateEditable(); $bundle->name = $request->input('name'); + $bundle->description = $request->input('description'); $bundle->published = (bool) $request->input('published', false); $bundle->saveOrFail(); @@ -200,6 +203,11 @@ public function exportLocalBundle(Bundle $bundle) return ['payloads' => $bundle->export()]; } + public function exportLocalBundleSettings(Bundle $bundle) + { + return ['settings' => $bundle->exportSettings()]; + } + public function exportLocalAsset(Request $request) { $asset = $request->input('class')::findOrFail($request->input('id')); @@ -212,7 +220,12 @@ public function addAsset(Request $request, Bundle $bundle) $asset = $request->input('type')::findOrFail($request->input('id')); $bundle->addAsset($asset); } - + + public function addSettings(Request $request, Bundle $bundle) + { + $bundle->addSettings($request->input('setting'), $request->input('config')); + } + public function addAssetToBundles(Request $request) { $bundles = $request->input('bundles'); @@ -290,4 +303,11 @@ public function deleteBundleAsset(BundleAsset $bundleAsset) return response()->json(['message' => 'Bundle asset association deleted.'], 200); } + + public function deleteBundleSetting(BundleSetting $bundleSetting) + { + $bundleSetting->delete(); + + return response()->json(['message' => 'Bundle setting deleted.'], 200); + } } diff --git a/ProcessMaker/Models/Bundle.php b/ProcessMaker/Models/Bundle.php index a53fa3ceef..31112a4a8b 100644 --- a/ProcessMaker/Models/Bundle.php +++ b/ProcessMaker/Models/Bundle.php @@ -45,6 +45,11 @@ public function assets() return $this->hasMany(BundleAsset::class); } + public function settings() + { + return $this->hasMany(BundleSetting::class); + } + public function devLink() { return $this->belongsTo(DevLink::class, 'dev_link_id'); @@ -72,6 +77,13 @@ public function export() return $exports; } + public function exportSettings() + { + return $this->settings()->get()->map(function ($setting) { + return $setting->export(); + }); + } + public function syncAssets($assets) { $assetKeys = []; @@ -125,7 +137,23 @@ public function addAsset(ProcessMakerModel $asset) 'asset_id' => $asset->id, ]); } - + + public function addSettings($setting, $config) + { + $exists = $this->settings()->where('setting', $setting)->exists(); + if ($exists) { + $this->settings()->where('setting', $setting)->update([ + 'config' => $config, + ]); + } else { + BundleSetting::create([ + 'bundle_id' => $this->id, + 'setting' => $setting, + 'config' => $config, + ]); + } + } + public function addAssetToBundles(ProcessMakerModel $asset) { $message = null; @@ -134,6 +162,7 @@ public function addAssetToBundles(ProcessMakerModel $asset) } catch (ValidationException $ve) { $message = $ve->getMessage(); } + return $message; } @@ -184,6 +213,19 @@ public function savePayloadsToFile(array $payloads) } } + public function installSettings($settings) + { + $newSettingsKeys = collect($settings)->pluck('setting')->toArray(); + + $this->settings() + ->whereNotIn('setting', $newSettingsKeys) + ->delete(); + + foreach ($settings as $setting) { + $this->addSettings($setting['setting'], $setting['config']); + } + } + public function install(array $payloads, $mode, $logger = null) { if ($logger === null) { diff --git a/ProcessMaker/Models/BundleAsset.php b/ProcessMaker/Models/BundleAsset.php index 3cb95de6b5..a8948c7f45 100644 --- a/ProcessMaker/Models/BundleAsset.php +++ b/ProcessMaker/Models/BundleAsset.php @@ -11,7 +11,15 @@ class BundleAsset extends ProcessMakerModel protected $guarded = ['id']; - protected $appends = ['name', 'url', 'type']; + protected $appends = ['name', 'url', 'type', 'owner_name', 'categories']; + + const DATA_SOURCE_CLASS = 'ProcessMaker\Packages\Connectors\DataSources\Models\DataSource'; + + const COLLECTION_CLASS = 'ProcessMaker\Plugins\Collections\Models\Collection'; + + const DECISION_TABLE_CLASS = 'ProcessMaker\Package\PackageDecisionEngine\Models\DecisionTable'; + + const FLOW_GENIE_CLASS = 'ProcessMaker\Package\PackageAi\Models\FlowGenie'; protected static function boot() { @@ -53,7 +61,7 @@ public function getNameAttribute() $this->asset_type === Screen::class || $this->asset_type === Script::class ) { - return $this->title; + return $this->asset->title; } return $this->asset->name; @@ -68,6 +76,14 @@ public function getUrlAttribute() return "/designer/scripts/{$this->asset_id}/builder"; case Process::class: return "/modeler/{$this->asset_id}"; + case self::DATA_SOURCE_CLASS: + return "/designer/data-sources/{$this->asset_id}/edit"; + case self::COLLECTION_CLASS: + return "/collections/{$this->asset_id}/edit"; + case self::DECISION_TABLE_CLASS: + return "/designer/decision-tables/table-builder/{$this->asset_id}/edit"; + case self::FLOW_GENIE_CLASS: + return "/designer/flow-genies/{$this->asset_id}/edit"; default: return null; } @@ -82,8 +98,38 @@ public function getTypeAttribute() return 'Script'; case Process::class: return 'Process'; + case self::DATA_SOURCE_CLASS: + return 'data_source'; + case self::COLLECTION_CLASS: + return 'collection'; + case self::DECISION_TABLE_CLASS: + return 'decision_table'; + case self::FLOW_GENIE_CLASS: + return 'flow_genie'; default: return null; } } + + public function getOwnerNameAttribute() + { + if ($this->asset && method_exists($this->asset, 'user')) { + return $this->asset->user->firstname . ' ' . $this->asset->user->lastname; + } + + return null; + } + + public function getCategoriesAttribute() + { + if ($this->asset_type === self::COLLECTION_CLASS) { + return []; + } + + if ($this->asset && method_exists($this->asset, 'categories')) { + return $this->asset->categories->pluck('name')->toArray(); + } + + return []; + } } diff --git a/ProcessMaker/Models/BundleSetting.php b/ProcessMaker/Models/BundleSetting.php new file mode 100644 index 0000000000..35de7bf8dc --- /dev/null +++ b/ProcessMaker/Models/BundleSetting.php @@ -0,0 +1,34 @@ + 'array', + ]; + + public function bundle() + { + return $this->belongsTo(Bundle::class); + } + + public function export() + { + return [ + 'setting' => $this->setting, + 'config' => $this->config, + ]; + } +} diff --git a/ProcessMaker/Models/DevLink.php b/ProcessMaker/Models/DevLink.php index 12c0864357..cf831d0210 100644 --- a/ProcessMaker/Models/DevLink.php +++ b/ProcessMaker/Models/DevLink.php @@ -143,6 +143,10 @@ public function installRemoteBundle($remoteBundleId, $updateType) route('api.devlink.export-local-bundle', ['bundle' => $remoteBundleId], false) )->json(); + $bundleSettingsExport = $this->client()->get( + route('api.devlink.export-local-bundle-settings', ['bundle' => $remoteBundleId], false) + )->json(); + $bundle = Bundle::updateOrCreate( [ 'remote_id' => $remoteBundleId, @@ -156,7 +160,7 @@ public function installRemoteBundle($remoteBundleId, $updateType) ); $bundle->install($bundleExport['payloads'], $updateType, $this->logger); - + $bundle->installSettings($bundleSettingsExport['settings']); $this->logger->setStatus('done'); } diff --git a/database/migrations/2024_11_26_145144_add_description_to_bundles_table.php b/database/migrations/2024_11_26_145144_add_description_to_bundles_table.php new file mode 100644 index 0000000000..26f93cef62 --- /dev/null +++ b/database/migrations/2024_11_26_145144_add_description_to_bundles_table.php @@ -0,0 +1,27 @@ +text('description')->after('name')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('bundles', function (Blueprint $table) { + $table->dropColumn('description'); + }); + } +}; diff --git a/database/migrations/2024_12_03_140610_create_bundle_settings_table.php b/database/migrations/2024_12_03_140610_create_bundle_settings_table.php new file mode 100644 index 0000000000..7da3fae505 --- /dev/null +++ b/database/migrations/2024_12_03_140610_create_bundle_settings_table.php @@ -0,0 +1,31 @@ +id(); + $table->unsignedBigInteger('bundle_id'); + $table->string('setting'); + $table->json('config')->nullable(); + $table->timestamps(); + + $table->index(['bundle_id', 'setting']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('bundle_settings'); + } +}; diff --git a/devhub/pm-font/svg/edit-outline.svg b/devhub/pm-font/svg/edit-outline.svg new file mode 100644 index 0000000000..5f6721106e --- /dev/null +++ b/devhub/pm-font/svg/edit-outline.svg @@ -0,0 +1,3 @@ + + + diff --git a/devhub/pm-font/svg/link-icon.svg b/devhub/pm-font/svg/link-icon.svg new file mode 100644 index 0000000000..1608f95ec0 --- /dev/null +++ b/devhub/pm-font/svg/link-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/devhub/pm-font/svg/plus-thin.svg b/devhub/pm-font/svg/plus-thin.svg new file mode 100644 index 0000000000..ef88e8a85a --- /dev/null +++ b/devhub/pm-font/svg/plus-thin.svg @@ -0,0 +1,3 @@ + + + diff --git a/devhub/pm-font/svg/remove-outlined.svg b/devhub/pm-font/svg/remove-outlined.svg new file mode 100644 index 0000000000..dcb2c5838d --- /dev/null +++ b/devhub/pm-font/svg/remove-outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/fonts/pm-font/index.html b/resources/fonts/pm-font/index.html index 281a2aa4c4..b5f9bc7fa0 100644 --- a/resources/fonts/pm-font/index.html +++ b/resources/fonts/pm-font/index.html @@ -103,7 +103,7 @@
-

ProcessMaker Icons4.12.0+alpha-3

+

ProcessMaker Icons4.12.0+beta-5

Icons generated with svgtofont. For add new icons, please check the README file
@@ -115,7 +115,7 @@

ProcessMaker Icons4.12.0+alpha-3

-

ProcessMaker Icons4.12.0+alpha-3

+

ProcessMaker Icons4.12.0+beta-5

Icons generated with svgtofont. For add new icons, please check the README file
@@ -261,6 +261,13 @@

fp-copy

fp-desktop

+
  • + +

    fp-edit-outline

    +
  • +
  • fp-github

    fp-layout-icon

  • +
  • + +

    fp-link-icon

    +
  • +
  • fp-pdf

    fp-play-outline

  • +
  • + +

    fp-plus-thin

    +
  • +
  • fp-play-outline

    fp-plus

  • +
  • + +

    fp-remove-outlined

    +
  • +
  • -

    ProcessMaker Icons4.12.0+alpha-3

    +

    ProcessMaker Icons4.12.0+beta-5

    Icons generated with svgtofont. For add new icons, please check the README file
    @@ -134,7 +134,7 @@

    ProcessMaker Icons4.12.0+alpha-3

      -
    • bpmn-action-by-email

      
    • bpmn-data-connector

      
    • bpmn-data-object

      
    • bpmn-data-store

      
    • bpmn-docusign

      
    • bpmn-end-event

      
    • bpmn-flowgenie

      
    • bpmn-gateway

      
    • bpmn-generic-gateway

      
    • bpmn-idp

      
    • bpmn-intermediate-event

      
    • bpmn-pool

      
    • bpmn-send-email

      
    • bpmn-start-event

      
    • bpmn-task

      
    • bpmn-text-annotation

      
    • brush-icon

      
    • close

      
    • cloud-download-outline

      
    • copy

      
    • desktop

      
    • eye

      
    • fields-icon

      
    • flowgenie-outline

      
    • folder-outline

      
    • fullscreen

      
    • github

      
    • layout-icon

      
    • map

      
    • mobile

      
    • pdf

      
    • play-outline

      
    • plus

      
    • screen-outline

      
    • script-outline

      
    • slack-notification

      
    • slack

      
    • slideshow

      
    • table

      
    • trash

      
    • unlink

      
    • +
    • bpmn-action-by-email

      
    • bpmn-data-connector

      
    • bpmn-data-object

      
    • bpmn-data-store

      
    • bpmn-docusign

      
    • bpmn-end-event

      
    • bpmn-flowgenie

      
    • bpmn-gateway

      
    • bpmn-generic-gateway

      
    • bpmn-idp

      
    • bpmn-intermediate-event

      
    • bpmn-pool

      
    • bpmn-send-email

      
    • bpmn-start-event

      
    • bpmn-task

      
    • bpmn-text-annotation

      
    • brush-icon

      
    • close

      
    • cloud-download-outline

      
    • copy

      
    • desktop

      
    • edit-outline

      
    • eye

      
    • fields-icon

      
    • flowgenie-outline

      
    • folder-outline

      
    • fullscreen

      
    • github

      
    • layout-icon

      
    • link-icon

      
    • map

      
    • mobile

      
    • pdf

      
    • play-outline

      
    • plus-thin

      
    • plus

      
    • remove-outlined

      
    • screen-outline

      
    • script-outline

      
    • slack-notification

      
    • slack

      
    • slideshow

      
    • table

      
    • trash

      
    • unlink

      