Skip to content

Commit

Permalink
[6.x] Refator js (#1662)
Browse files Browse the repository at this point in the history
* Add wire:replace.self

* Refactoring javascript
  • Loading branch information
luanfreitasdev authored Aug 29, 2024
1 parent 912e58a commit 4914703
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 93 deletions.
2 changes: 1 addition & 1 deletion dist/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"/powergrid.js": "/powergrid.js?id=270c25cfa4d7b8f71de48a2408d1dd56",
"/powergrid.js": "/powergrid.js?id=9420b22618424ae86b2ded1f4d726748",
"/bootstrap5.css": "/bootstrap5.css?id=a27af22343149104b2aa3283d8fd502b",
"/tailwind.css": "/tailwind.css?id=924477e2afcb2cb56aa392e266ee56ca"
}
2 changes: 1 addition & 1 deletion dist/powergrid.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion resources/config/livewire-powergrid.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
'theme' => \PowerComponents\LivewirePowerGrid\Themes\Tailwind::class,
//'theme' => \PowerComponents\LivewirePowerGrid\Themes\Bootstrap5::class,

'cache_ttl' => 3600,
'cache_ttl' => null,

'icon_resources' => [
'paths' => [
Expand Down
153 changes: 86 additions & 67 deletions resources/js/components/pg-render-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ export default (params) => ({
cookieKey: null,
parentId: params?.parentId ?? null,
init() {
if (this.rowId == null) {
return;
}

this.setKeys();

window.addEventListener('beforeunload', () => {
Expand All @@ -22,12 +26,9 @@ export default (params) => ({
return localStorage.getItem(this.storageKey);
}

let actions
if (this.rowId) {
actions = window[`pgActions_${this.parentId ?? this.$wire.id}`][this.rowId];
} else {
actions = window[`pgActionsHeader_${this.$wire.id}`];
}
const actions = this.rowId
? window[`pgActions_${this.parentId ?? this.$wire.id}`][this.rowId]
: window[`pgActionsHeader_${this.$wire.id}`];

if (typeof actions !== "object") {
return '';
Expand All @@ -36,75 +37,22 @@ export default (params) => ({
let html = ''

actions.forEach((action) => {
let hideAction = false;
let replaceHtml = null;

if (action.rules && Object.values(action.rules).length > 0) {
Object.values(action.rules).forEach((ruleObj) => {
if (ruleObj.apply) {
if (ruleObj.rule.hide) {
hideAction = true;
} else if (ruleObj.rule.setAttribute) {
ruleObj.rule.setAttribute.forEach(attrRule => {
if (action.attributes[attrRule.attribute]) {
action.attributes[attrRule.attribute] += ` ${attrRule.value}`;
} else {
action.attributes[attrRule.attribute] = attrRule.value;
}
});
}
if (ruleObj.replaceHtml) {
replaceHtml = ruleObj.replaceHtml;
}
}
});
}
let hideAction = this.shouldHideAction(action);
let replaceHtml = this.getReplaceHtml(action);

if (!hideAction) {
if (replaceHtml) {
html += replaceHtml;
} else {
let attributesStr = '';

Object.entries(action.attributes).forEach(([key, value]) => {
attributesStr += ` ${key}="${value}"`;
});
let attributesStr = this.buildAttributesString(action.attributes);

if (action.icon) {
const iconAttributesStr = Object.entries(action.iconAttributes)
.filter(([key, value]) => value != null)
.map(([key, value]) => `${key}="${value}"`)
.join(' ');

let iconHtml = window.pgResourceIcons[action.icon];

if (typeof iconHtml === "undefined") {
console.warn(`PowerGrid: Unable to load icons in javascript window in row: [${this.rowId}]`)
return;
}

iconHtml = iconHtml.replace(/<([^\s>]+)([^>]*)>/, (match, tagName, existingAttributes) => {
let updatedAttributes = existingAttributes.trim();
const newAttributes = iconAttributesStr.replace(/class="([^"]*)"/, (classMatch, newClass) => {
if (updatedAttributes.includes('class=')) {
updatedAttributes = updatedAttributes.replace(/class="([^"]*)"/, (classMatch, existingClass) =>
`class="${existingClass} ${newClass.trim()}"`
);
} else {
updatedAttributes += ` ${classMatch}`;
}
return '';
});
return `<${tagName} ${updatedAttributes} ${newAttributes}>`;
});

if (action.slot) {
html += `<${action.tag ?? 'button'} ${attributesStr}>${iconHtml} ${action.slot}</${action.tag ?? 'button'}>`;
} else {
html += `<${action.tag ?? 'button'} ${attributesStr}>${iconHtml}</${action.tag ?? 'button'}>`;
}
let iconHtml = this.processIcon(action);
if (!iconHtml) return;

html += this.buildActionHtmlWithIcon(action, attributesStr, iconHtml);
} else {
html += `<${action.tag ?? 'button'} ${attributesStr}>${action.slot}</${action.tag ?? 'button'}>`;
html += this.buildActionHtml(action, attributesStr);
}
}
}
Expand All @@ -119,6 +67,77 @@ export default (params) => ({
return html;
},

shouldHideAction(action) {
let hideAction = false;
if (action.rules && Object.values(action.rules).length > 0) {
Object.values(action.rules).forEach((ruleObj) => {
if (ruleObj.apply && ruleObj.rule.hide) {
hideAction = true;
}
});
}
return hideAction;
},

getReplaceHtml(action) {
let replaceHtml = null;
if (action.rules && Object.values(action.rules).length > 0) {
Object.values(action.rules).forEach((ruleObj) => {
if (ruleObj.apply && ruleObj.replaceHtml) {
replaceHtml = ruleObj.replaceHtml;
}
});
}
return replaceHtml;
},

buildAttributesString(attributes) {
return Object.entries(attributes)
.map(([key, value]) => ` ${key}="${value}"`)
.join('');
},

processIcon(action) {
const iconAttributesStr = this.buildAttributesString(action.iconAttributes);
let iconHtml = window.pgResourceIcons[action.icon];

if (typeof iconHtml === "undefined") {
console.warn(`PowerGrid: Unable to load icons in javascript window in row: [${this.rowId}]`);
return null;
}

return this.replaceIconAttributes(iconHtml, iconAttributesStr);
},

replaceIconAttributes(iconHtml, iconAttributesStr) {
return iconHtml.replace(/<([^\s>]+)([^>]*)>/, (match, tagName, existingAttributes) => {
let updatedAttributes = existingAttributes.trim();
const newAttributes = iconAttributesStr.replace(/class="([^"]*)"/, (classMatch, newClass) => {
if (updatedAttributes.includes('class=')) {
updatedAttributes = updatedAttributes.replace(/class="([^"]*)"/, (classMatch, existingClass) =>
`class="${existingClass} ${newClass.trim()}"`
);
} else {
updatedAttributes += ` ${classMatch}`;
}
return '';
});
return `<${tagName} ${updatedAttributes} ${newAttributes}>`;
});
},

buildActionHtmlWithIcon(action, attributesStr, iconHtml) {
if (action.slot) {
return `<${action.tag ?? 'button'} ${attributesStr}>${iconHtml} ${action.slot}</${action.tag ?? 'button'}>`;
}

return `<${action.tag ?? 'button'} ${attributesStr}>${iconHtml}</${action.tag ?? 'button'}>`;
},

buildActionHtml(action, attributesStr) {
return `<${action.tag ?? 'button'} ${attributesStr}>${action.slot}</${action.tag ?? 'button'}>`;
},

checkLocalStorageFreeSpace() {
const maxLocalStorageSize = 2 * 1024 * 1024; // 2MB
let totalSize = 0;
Expand Down
1 change: 1 addition & 0 deletions resources/views/components/table.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class="{{ $class }}"
@endphp

<tr
wire:replace.self
x-data="pgRowAttributes({ rowId: @js($rowId), defaultClasses: @js($class), rules: @js($row->__powergrid_rules) })"
x-bind="getAttributes"
>
Expand Down
27 changes: 19 additions & 8 deletions src/Concerns/HasActions.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ public function prepareActionsResources(): ?string
return null;
}

/** @var string $records */
$records = !app()->hasDebugModeEnabled() ? Cache::remember('pg-resource-icons-json', intval(config('livewire-powergrid.cache_ttl')), function (): string {
return $this->getResourceIconsJson();
}) : $this->getResourceIconsJson();
$closure = fn () => $this->getResourceIconsJson();

if (intval(config('livewire-powergrid.cache_ttl')) > 0) {
$records = strval(Cache::remember('pg-resource-icons-json', intval(config('livewire-powergrid.cache_ttl')), $closure));
} else {
$records = (string) $closure();
}

$this->js(<<<JS
this.pgResourceIcons = $records
Expand Down Expand Up @@ -156,14 +159,22 @@ public function prepareActionRulesForRows(mixed $row, ?object $loop = null): arr
$value = strval(data_get($row, $this->realPrimaryKey));
$cacheKey = "pg-prepare-action-rules-for-rows-{$this->getId()}-{$value}}";

/** @var array $formattedRules */
$formattedRules = Cache::remember($cacheKey, intval(config('livewire-powergrid.cache_ttl')), function () use ($closure, $row, $loop) {
if (intval(config('livewire-powergrid.cache_ttl') > 0)) {
/** @var array $formattedRules */
$formattedRules = Cache::remember($cacheKey, intval(config('livewire-powergrid.cache_ttl')), function () use ($closure, $row, $loop) {
$value = $closure($row, $loop);

return array_filter($value, function ($item) {
return !empty($item);
});
});
} else {
$value = $closure($row, $loop);

return array_filter($value, function ($item) {
$formattedRules = array_filter($value, function ($item) {
return !empty($item);
});
});
}

return $formattedRules;
}
Expand Down
26 changes: 11 additions & 15 deletions src/PowerGridComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,14 @@ protected function getRecords(): mixed
return collect();
}

$start = microtime(true);

if (boolval(data_get($this->setUp, 'cache.enabled')) && Cache::supportsTags()) {
return $this->getRecordsFromCache($start);
return $this->getRecordsFromCache();
}

return $this->getRecordsDataSource($start);
return $this->getRecordsDataSource();
}

private function getRecordsFromCache(float $start): mixed
private function getRecordsFromCache(): mixed
{
$prefix = strval(data_get($this->setUp, 'cache.prefix'));
$customTag = strval(data_get($this->setUp, 'cache.tag'));
Expand All @@ -147,12 +145,10 @@ private function getRecordsFromCache(float $start): mixed
$results = Cache::tags($tag)->remember($cacheKey, $ttl, fn () => ProcessDataSource::make($this)->get());

if ($this->measurePerformance) {
$time = round((microtime(true) - $start) * 1000);

app(Dispatcher::class)->dispatch(
new PowerGridPerformanceData(
tableName: $this->tableName,
retrieveDataInMs: $time,
retrieveDataInMs: 0,
isCached: true,
)
);
Expand All @@ -161,21 +157,21 @@ private function getRecordsFromCache(float $start): mixed
return $results;
}

private function getRecordsDataSource(float $start): Paginator|MorphToMany|\Illuminate\Contracts\Pagination\LengthAwarePaginator|LengthAwarePaginator|BaseCollection
private function getRecordsDataSource(): Paginator|MorphToMany|\Illuminate\Contracts\Pagination\LengthAwarePaginator|LengthAwarePaginator|BaseCollection
{
if ($this->measurePerformance) {
DB::enableQueryLog();
}

$results = ProcessDataSource::make($this)->get();
$start = microtime(true);
$results = ProcessDataSource::make($this)->get();
$retrieveData = round((microtime(true) - $start) * 1000);

if ($this->measurePerformance) {
$queries = DB::getQueryLog();

DB::disableQueryLog();

$retrieveData = round((microtime(true) - $start) * 1000);

/** @var float $queriesTime */
$queriesTime = collect($queries)->sum('time');

Expand Down Expand Up @@ -256,13 +252,13 @@ public function render(): Application|Factory|View
$cacheKey = 'lazy-tmp-' . $this->getId() . '-' . implode('-', $this->getCacheKeys());

$data = Cache::remember($cacheKey, 60, fn () => $this->getRecords());

/** @phpstan-ignore-next-line */
$this->totalCurrentPage = method_exists($data, 'items') ? count($data->items()) : $data->count();
} else {
$data = $this->getRecords();
}

/** @phpstan-ignore-next-line */
$this->totalCurrentPage = method_exists($data, 'items') ? count($data->items()) : $data->count();

$this->storeActionsRowInJSWindow();

$this->storeActionsHeaderInJSWindow();
Expand Down

0 comments on commit 4914703

Please sign in to comment.