Some code optimisation and de-duplication with components

This commit is contained in:
Deon George 2025-01-15 23:29:53 +11:00
parent 8b922b2e8b
commit 6e06caa83b
15 changed files with 169 additions and 101 deletions

View File

@ -247,9 +247,9 @@ class Attribute implements \Countable, \ArrayAccess
/**
* Display the attribute value
*
* @param bool $edit
* @param bool $old
* @param bool $new
* @param bool $edit Render an edit form
* @param bool $old Use old value
* @param bool $new Enable adding values
* @return View
*/
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View

View File

@ -45,7 +45,9 @@ class Entry extends Model
*/
public function getAttributes(): array
{
return $this->objects->map(function($item) { return $item->values->toArray(); })->toArray();
return $this->objects
->map(fn($item)=>$item->values->toArray())
->toArray();
}
/**
@ -55,16 +57,14 @@ class Entry extends Model
{
$key = $this->normalizeAttributeKey($key);
if ((! array_key_exists($key, $this->original)) && (! $this->objects->has($key))) {
if ((! array_key_exists($key,$this->original)) && (! $this->objects->has($key)))
return TRUE;
}
$current = $this->attributes[$key];
$original = $this->objects->get($key)->values;
if ($current === $original) {
return true;
}
if ($current === $original)
return TRUE;
return ! $this->getObject($key)->isDirty();
}
@ -134,8 +134,8 @@ class Entry extends Model
/**
* Return a key to use for sorting
*
* @todo This should be the DN in reverse order
* @return string
* @todo This should be the DN in reverse order
*/
public function getSortKeyAttribute(): string
{
@ -148,7 +148,7 @@ class Entry extends Model
{
$key = $this->normalizeAttributeKey($key);
if (config('server')->schema('attributetypes')->has($key) === FALSE)
if (! config('server')->schema('attributetypes')->contains($key))
throw new AttributeException('Schema doesnt have attribute [%s]',$key);
if ($x=$this->objects->get($key)) {
@ -199,10 +199,10 @@ class Entry extends Model
}
}
$sort = collect(config('ldap.attr_display_order',[]))->transform(function($item) { return strtolower($item); });
$sort = collect(config('ldap.attr_display_order',[]))->map(fn($item)=>strtolower($item));
// Order the attributes
$result = $result->sortBy([function(Attribute $a,Attribute $b) use ($sort): int {
return $result->sortBy([function(Attribute $a,Attribute $b) use ($sort): int {
if ($a === $b)
return 0;
@ -226,8 +226,6 @@ class Entry extends Model
// return -1 if $a before $b in $attrs_display_order
return ($a_key < $b_key) ? -1 : 1;
}]);
return $result;
}
/**
@ -261,9 +259,8 @@ class Entry extends Model
*/
public function getInternalAttributes(): Collection
{
return $this->objects->filter(function($item) {
return $item->is_internal;
});
return $this->objects
->filter(fn($item)=>$item->is_internal);
}
/**
@ -274,7 +271,8 @@ class Entry extends Model
*/
public function getObject(string $key): Attribute|null
{
return $this->objects->get($this->normalizeAttributeKey($key));
return $this->objects
->get($this->normalizeAttributeKey($key));
}
public function getObjects(): Collection
@ -293,7 +291,8 @@ class Entry extends Model
*/
public function getMissingAttributes(): Collection
{
return $this->getAvailableAttributes()->diff($this->getVisibleAttributes());
return $this->getAvailableAttributes()
->diff($this->getVisibleAttributes());
}
/**
@ -303,14 +302,14 @@ class Entry extends Model
*/
public function getVisibleAttributes(): Collection
{
return $this->objects->filter(function($item) {
return ! $item->is_internal;
});
return $this->objects
->filter(fn($item)=>! $item->is_internal);
}
public function hasAttribute(int|string $key): bool
{
return $this->objects->has($key);
return $this->objects
->has($key);
}
/**

View File

@ -8,22 +8,22 @@ use App\Classes\LDAP\Attribute as LDAPAttribute;
class Attribute extends Component
{
public LDAPAttribute $o;
public ?LDAPAttribute $o;
public bool $edit;
public bool $new;
public bool $old;
public ?string $na;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct(LDAPAttribute $o,bool $edit,bool $old=FALSE,bool $new=FALSE)
public function __construct(?LDAPAttribute $o,bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $na=NULL)
{
$this->o = $o;
$this->edit = $edit;
$this->old = $old;
$this->new = $new;
$this->na = $na;
}
/**
@ -33,6 +33,9 @@ class Attribute extends Component
*/
public function render()
{
return $this->o->render($this->edit,$this->old,$this->new);
return $this->o
? $this->o
->render($this->edit,$this->old,$this->new)
: $this->na;
}
}

View File

@ -15,6 +15,6 @@
</div>
</div>
<x-attribute :o="$o" :edit="true" :new="$new"/>
<x-attribute :o="$o" :edit="true" :new="$new ?? FALSE"/>
</div>
</div>

View File

@ -1,9 +1,9 @@
<!-- $o=Attribute::class -->
<x-attribute.layout :edit="$edit" :new="$new" :o="$o">
@foreach (old($o->name_lc,$new ? [NULL] : $o->values) as $value)
@if ($edit && ! $o->is_rdn)
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o">
@foreach(old($o->name_lc,($new ?? FALSE) ? [NULL] : $o->values) as $value)
@if (($edit ?? FALSE) && ! $o->is_rdn)
<div class="input-group has-validation">
<input type="text" class="form-control @if($e=$errors->get($o->name_lc.'.'.$loop->index))is-invalid @endif mb-1 @if($o->values->search($value) === FALSE) border-focus @endif" name="{{ $o->name_lc }}[]" value="{{ $value }}" placeholder="{{ ! is_null($x=Arr::get($o->values,$loop->index)) ? $x : '['.__('NEW').']' }}" @if (! $new)readonly="true" @endif">
<input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>($o->values->contains($value))]) name="{{ $o->name_lc }}[]" value="{{ $value }}" placeholder="{{ ! is_null($x=Arr::get($o->values,$loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! ($new ?? FALSE))>
<div class="invalid-feedback pb-2">
@if($e)

View File

@ -9,7 +9,7 @@
@default
<td>
<input type="hidden" name="{{ $o->name_lc }}[]" value="{{ md5($value) }}">
<img class="jpegphoto @if($e=$errors->get($o->name_lc.'.'.$loop->index))is-invalid @endif" src="data:{{ $x }};base64, {{ base64_encode($value) }}" />
<img @class(['jpegphoto','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index))]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" />
@if ($edit)
<br>

View File

@ -1,5 +1,5 @@
<div class="row pt-2">
<div class="col-1 @if(! $edit)d-none @endif"></div>
<div @class(['col-1','d-none'=>(! $edit)])></div>
<div class="col-10 p-2">
<div id="{{ $o->name_lc }}">
{{ $slot }}

View File

@ -3,7 +3,7 @@
@foreach (old($o->name_lc,$o->values) as $value)
@if ($edit && ($value === NULL || (! $o->isStructural($value))))
<div class="input-group has-validation">
<input type="text" class="form-control @if($e=$errors->get($o->name_lc.'.'.$loop->index))is-invalid @endif mb-1 @if($o->values->search($value) === FALSE) border-focus @endif" name="{{ $o->name_lc }}[]" value="{{ $value }}" placeholder="{{ ! is_null($x=Arr::get($o->values,$loop->index)) ? $x : '['.__('NEW').']' }}" readonly="true">
<input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>$o->values->contains($value)]) name="{{ $o->name_lc }}[]" value="{{ $value }}" placeholder="{{ ! is_null($x=Arr::get($o->values,$loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(true)>
<div class="invalid-feedback pb-2">
@if($e)
{{ join('|',$e) }}

View File

@ -4,7 +4,7 @@
@foreach ($o->values as $value)
@if ($edit)
<div class="input-group has-validation">
<input type="password" class="form-control @if($e=$errors->get($o->name_lc.'.'.$loop->index))is-invalid @endif mb-1 @if($o->values->search($value) === FALSE) border-focus @endif" name="{{ $o->name_lc }}[]" value="{{ md5($value) }}" readonly="true">
<input type="password" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$loop->index)),'mb-1','border-focus'=>$o->values->contains($value)]) name="{{ $o->name_lc }}[]" value="{{ md5($value) }}" @readonly(true)>
<div class="invalid-feedback pb-2">
@if($e)

View File

@ -2,7 +2,7 @@
<span class="btn btn-sm btn-outline-focus mt-3"><i class="fas fa-fw fa-exchange"></i> @lang('Rename')</span>
@elseif($edit && $o->can_addvalues)
<span class="p-0 m-0">
<span class="btn btn-sm btn-outline-primary mt-3 addable @if(! $new)d-none @endif" id="{{ $o->name_lc }}"><i class="fas fa-fw fa-plus"></i> @lang('Add Value')</span>
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name_lc }}"><i class="fas fa-fw fa-plus"></i> @lang('Add Value')</span>
@if($new)
<script type="text/javascript">
$(document).ready(function() {

View File

@ -0,0 +1,29 @@
<div class="form-group">
@if(isset($label))
<label {{ $attributes->only(['class'])->merge(['class'=>'form-label']) }} for="{{ $id ?? $name }}">{!! html_entity_decode($label) !!}</label>
@endisset
<div class="input-group has-validation">
@if(isset($icon) || isset($prepend))
{{-- // messes with the icon box, we have rounded corners on the right side
<div class="input-group-prepend">
--}}
<span class="input-group-text">@isset($icon)<i class="bi {{ $icon }}"></i>@endisset @isset($prepend){!! $prepend !!}@endisset</span>
{{--
</div>
--}}
@endif
{{ $slot }}
@isset($name)
<span class="invalid-feedback">
@error((! empty($old)) ? $old : $name)
{{ $message }}
@elseif(isset($feedback))
{{ $feedback }}
@enderror
</span>
@endisset
</div>
@isset($helper)
<span class="input-helper">{!! html_entity_decode($helper) !!}</span>
@endif
</div>

View File

@ -0,0 +1,63 @@
<x-form.base {{ $attributes }}>
@isset($name)
<input type="hidden" id="{{ $name }}_disabled" name="{{ $name }}" value="" disabled>
@endisset
<select style="width: 80%" class="form-select @isset($name)@error((! empty($old)) ? $old : $name) is-invalid @enderror @endisset" id="{{ $id ?? $name }}" @isset($name)name="{{ $name }}"@endisset @required(isset($required) && $required) @disabled(isset($disabled) && $disabled)>
@if(empty($value) || isset($addnew) || isset($choose))
<option value=""></option>
@isset($addnew)
<option value="new">{{ $addnew ?: 'Add New' }}</option>
@endisset
@endif
@isset($options)
@empty($groupby)
@foreach($options as $option)
@continue(! Arr::get($option,'value'))
<option value="{{ Arr::get($option,'id') }}" @selected(isset($name) && (Arr::get($option,'id') == old($old ?? $name,$value ?? '')))>{{ Arr::get($option,'value') }}</option>
@endforeach
@else
@foreach($options->groupBy($groupby) as $group)
<optgroup label="{{ $groupby == 'active' ? (Arr::get($group->first(),$groupby) ? 'Active' : 'Not Active') : Arr::get($group->first(),$groupby) }}">
@foreach($group as $option)
@continue(! Arr::get($option,'value'))
<option value="{{ Arr::get($option,'id') }}" @selected(isset($name) && (Arr::get($option,'id') == old($old ?? $name,$value ?? '')))>{{ Arr::get($option,'value') }}</option>
@endforeach
</optgroup>
@endforeach
@endempty
@endisset
</select>
</x-form.base>
@section('page-scripts')
<script type="text/javascript">
// Select doesnt support read only so we'll use disable and a new field
@isset($name)
function {{$id ?? $name}}_readonly(on) {
if (on) {
$('#{{ $name }}').prop('disabled',true);
$('#{{ $name }}_disabled').prop('disabled',false).val($('#{{ $name }}').val());
} else {
$('#{{ $name }}').prop('disabled',false);
$('#{{ $name }}_disabled').prop('disabled',true);
}
}
@endisset
$(document).ready(function() {
$('#{{ $id ?? $name }}').select2({
theme: 'bootstrap-5',
dropdownAutoWidth: true,
width: 'style',
allowClear: true,
placeholder: '{{ $placeholder ?? '' }}',
@isset($addvalues)
tags: true,
@endisset
});
});
</script>
@append

View File

@ -0,0 +1,32 @@
<table class="table table-borderless">
<tr>
<td class="{{ ($x=$o->getObject('jpegphoto')) ? 'border' : '' }}" rowspan="2">
{!! $x ? $x->render(FALSE,TRUE) : sprintf('<div class="page-title-icon f32"><i class="%s"></i></div>',$o->icon() ?? "fas fa-info") !!}
</td>
<td class="text-end align-text-top p-0 {{ $x ? 'ps-5' : 'pt-2' }}"><strong>{{ $dn }}</strong></td>
</tr>
<tr>
<td class="line-height-1" style="font-size: 55%;vertical-align: bottom;" colspan="2">
<table>
<tr>
<td class="p-1 m-1">Created</td>
<th class="p-1 m-1">
<x-attribute :o="$o->getObject('createtimestamp')" :na="__('Unknown')"/> [<x-attribute :o="$o->getObject('creatorsname')" :na="__('Unknown')"/>]
</th>
</tr>
<tr>
<td class="p-1 m-1">Modified</td>
<th class="p-1 m-1">
<x-attribute :o="$o->getObject('modifytimestamp')" :na="__('Unknown')"/> [<x-attribute :o="$o->getObject('modifiersname')" :na="__('Unknown')"/>]
</th>
</tr>
<tr>
<td class="p-1 m-1">UUID</td>
<th class="p-1 m-1">
<x-attribute :o="$o->getObject('entryuuid')" :na="__('Unknown')"/>
</th>
</tr>
</table>
</td>
</tr>
</table>

View File

@ -1,30 +1,7 @@
@extends('layouts.dn')
@section('page_title')
<table class="table table-borderless">
<tr>
<td class="{{ ($x=$o->getObject('jpegphoto')) ? 'border' : '' }}" rowspan="2">{!! $x ? $x->render() : sprintf('<div class="page-title-icon f32"><i class="%s"></i></div>',$o->icon() ?? "fas fa-info") !!}</td>
<td class="text-end align-text-top p-0 {{ $x ? 'ps-5' : 'pt-2' }}"><strong>{{ $dn }}</strong></td>
</tr>
<tr>
<td class="line-height-1" style="font-size: 55%;vertical-align: bottom;" colspan="2">
<table>
<tr>
<td class="p-1 m-1">Created</td>
<th class="p-1 m-1">{{ ($x=$o->getObject('createtimestamp')) ? $x->render() : __('Unknown') }} [{{ ($x=$o->getObject('creatorsname')) ? $x->render() : __('Unknown') }}]</th>
</tr>
<tr>
<td class="p-1 m-1">Modified</td>
<th class="p-1 m-1">{{ ($x=$o->getObject('modifytimestamp')) ? $x->render() : __('Unknown') }} [{{ ($x=$o->getObject('modifiersname')) ? $x->render() : __('Unknown') }}]</th>
</tr>
<tr>
<td class="p-1 m-1">UUID</td>
<th class="p-1 m-1">{{ $o->entryuuid[0] ?? '' }}</th>
</tr>
</table>
</td>
</tr>
</table>
@include('fragment.dn.header')
@endsection
@section('main-content')
@ -74,13 +51,7 @@
<div class="row">
<div class="col-12 pt-2">
<label for="newattr" class="form-label">Select from...</label>
<select class="form-select" id="newattr">
<option value="">&nbsp;</option>
@foreach ($o->getMissingAttributes() as $ao)
<option value="{{ $ao->name_lc }}">{{ $ao->name }}</option>
@endforeach
</select>
<x-form.select id="newattr" label="Select from..." :options="$o->getMissingAttributes()->sortBy('name')->map(fn($item)=>['id'=>$item->name,'value'=>$item->name_lc])"/>
</div>
</div>
@endif

View File

@ -1,36 +1,7 @@
@extends('home')
@section('page_title')
<table class="table table-borderless">
<tr>
<td class="{{ ($x=$o->getObject('jpegphoto')) ? 'border' : '' }}" rowspan="2">
{!! $x ? $x->render(FALSE,TRUE) : sprintf('<div class="page-title-icon f32"><i class="%s"></i></div>',$o->icon() ?? "fas fa-info") !!}
</td>
<td class="text-end align-text-top p-0 {{ $x ? 'ps-5' : 'pt-2' }}"><strong>{{ $dn }}</strong></td>
</tr>
<tr>
<td class="line-height-1" style="font-size: 55%;vertical-align: bottom;" colspan="2">
<table>
<tr>
<td class="p-1 m-1">Created</td>
<th class="p-1 m-1">
{{ ($x=$o->getObject('createtimestamp')) ? $x->render() : __('Unknown') }} [{{ ($x=$o->getObject('creatorsname')) ? $x->render() : __('Unknown') }}]
</th>
</tr>
<tr>
<td class="p-1 m-1">Modified</td>
<th class="p-1 m-1">
{{ ($x=$o->getObject('modifytimestamp')) ? $x->render() : __('Unknown') }} [{{ ($x=$o->getObject('modifiersname')) ? $x->render() : __('Unknown') }}]
</th>
</tr>
<tr>
<td class="p-1 m-1">UUID</td>
<th class="p-1 m-1">{{ $o->entryuuid[0] ?? '' }}</th>
</tr>
</table>
</td>
</tr>
</table>
@include('fragment.dn.header')
@endsection
@section('main-content')