Compare commits

...

4 Commits

Author SHA1 Message Date
60507800a6 Revert version to 2.1.2-dev
All checks were successful
Create Docker Image / Test Application (x86_64) (push) Successful in 29s
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 1m25s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 4m31s
Create Docker Image / Final Docker Image Manifest (push) Successful in 10s
2025-04-30 09:04:10 +09:30
64cc21d819 Fix logic processing isDirty() for MD5Update apps by checking that the new & old values dont equal before checking their md5 value 2025-04-30 09:04:10 +09:30
3d511f3fae Change rendering of notes/errors/update and highlight attributes that are successfully updated 2025-04-30 09:04:10 +09:30
bab5a2626d Remove Components/AttributeType::class it wasnt providing any functionality 2025-04-30 09:04:10 +09:30
37 changed files with 126 additions and 136 deletions

View File

@ -307,15 +307,17 @@ class Attribute implements \Countable, \ArrayAccess
* @param bool $edit Render an edit form * @param bool $edit Render an edit form
* @param bool $old Use old value * @param bool $old Use old value
* @param bool $new Enable adding values * @param bool $new Enable adding values
* @param string $langtag Langtag to use when rendering these attribute values
* @param bool $updated Has the entry been updated (uses rendering highlights))
* @return View * @return View
*/ */
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
$view = match ($this->schema?->syntax_oid) { $view = match ($this->schema?->syntax_oid) {
self::SYNTAX_CERTIFICATE => view('components.syntax.certificate'), self::SYNTAX_CERTIFICATE => view('components.syntax.certificate'),
self::SYNTAX_CERTIFICATE_LIST => view('components.syntax.certificatelist'), self::SYNTAX_CERTIFICATE_LIST => view('components.syntax.certificatelist'),
default => view()->exists($x = 'components.attribute.' . $this->name_lc) default => view()->exists($x='components.attribute.'.$this->name_lc)
? view($x) ? view($x)
: view('components.attribute'), : view('components.attribute'),
}; };
@ -324,7 +326,9 @@ class Attribute implements \Countable, \ArrayAccess
->with('o',$this) ->with('o',$this)
->with('edit',$edit) ->with('edit',$edit)
->with('old',$old) ->with('old',$old)
->with('new',$new); ->with('new',$new)
->with('langtag',$langtag)
->with('updated',$updated);
} }
public function render_item_old(string $dotkey): ?string public function render_item_old(string $dotkey): ?string

View File

@ -15,7 +15,7 @@ final class JpegPhoto extends Binary
{ {
use MD5Updates; use MD5Updates;
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
return view('components.attribute.binary.jpegphoto') return view('components.attribute.binary.jpegphoto')
->with('o',$this) ->with('o',$this)
@ -23,6 +23,7 @@ final class JpegPhoto extends Binary
->with('old',$old) ->with('old',$old)
->with('new',$new) ->with('new',$new)
->with('langtag',$langtag) ->with('langtag',$langtag)
->with('updated',$updated)
->with('f',new \finfo); ->with('f',new \finfo);
} }
} }

View File

@ -9,5 +9,4 @@ use App\Classes\LDAP\Attribute;
*/ */
final class GidNumber extends Attribute final class GidNumber extends Attribute
{ {
protected(set) bool $no_attr_tags = FALSE;
} }

View File

@ -5,6 +5,7 @@ namespace App\Classes\LDAP\Attribute;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use App\Classes\LDAP\Attribute; use App\Classes\LDAP\Attribute;
use App\Ldap\Entry;
/** /**
* Represents an attribute whose values are internal * Represents an attribute whose values are internal
@ -14,7 +15,7 @@ abstract class Internal extends Attribute
protected(set) bool $is_internal = TRUE; protected(set) bool $is_internal = TRUE;
protected(set) bool $no_attr_tags = TRUE; protected(set) bool $no_attr_tags = TRUE;
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
// @note Internal attributes cannot be edited // @note Internal attributes cannot be edited
return view('components.attribute.internal') return view('components.attribute.internal')

View File

@ -5,13 +5,14 @@ namespace App\Classes\LDAP\Attribute\Internal;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use App\Classes\LDAP\Attribute\Internal; use App\Classes\LDAP\Attribute\Internal;
use App\Ldap\Entry;
/** /**
* Represents an attribute whose values are timestamps * Represents an attribute whose values are timestamps
*/ */
final class Timestamp extends Internal final class Timestamp extends Internal
{ {
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
// @note Internal attributes cannot be edited // @note Internal attributes cannot be edited
return view('components.attribute.internal.timestamp') return view('components.attribute.internal.timestamp')

View File

@ -3,9 +3,9 @@
namespace App\Classes\LDAP\Attribute; namespace App\Classes\LDAP\Attribute;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use Illuminate\Support\Arr;
use App\Classes\LDAP\Attribute; use App\Classes\LDAP\Attribute;
use App\Ldap\Entry;
use App\Traits\MD5Updates; use App\Traits\MD5Updates;
/** /**
@ -17,13 +17,14 @@ final class KrbPrincipalKey extends Attribute
protected(set) bool $no_attr_tags = TRUE; protected(set) bool $no_attr_tags = TRUE;
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
return view('components.attribute.krbprincipalkey') return view('components.attribute.krbprincipalkey')
->with('o',$this) ->with('o',$this)
->with('edit',$edit) ->with('edit',$edit)
->with('old',$old) ->with('old',$old)
->with('new',$new); ->with('new',$new)
->with('updated',$updated);
} }
public function render_item_old(string $dotkey): ?string public function render_item_old(string $dotkey): ?string

View File

@ -6,6 +6,7 @@ use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use App\Classes\LDAP\Attribute; use App\Classes\LDAP\Attribute;
use App\Ldap\Entry;
/** /**
* Represents an attribute whose value is a Kerberos Ticket Flag * Represents an attribute whose value is a Kerberos Ticket Flag
@ -49,13 +50,14 @@ final class KrbTicketFlags extends Attribute
return $helpers; return $helpers;
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
return view('components.attribute.krbticketflags') return view('components.attribute.krbticketflags')
->with('o',$this) ->with('o',$this)
->with('edit',$edit) ->with('edit',$edit)
->with('old',$old) ->with('old',$old)
->with('new',$new) ->with('new',$new)
->with('updated',$updated)
->with('helper',static::helpers()); ->with('helper',static::helpers());
} }
} }

View File

@ -70,14 +70,14 @@ final class ObjectClass extends Attribute
->contains($value); ->contains($value);
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
return view('components.attribute.objectclass') return view('components.attribute.objectclass')
->with('o',$this) ->with('o',$this)
->with('edit',$edit) ->with('edit',$edit)
->with('langtag',Entry::TAG_NOTAG)
->with('old',$old) ->with('old',$old)
->with('new',$new); ->with('new',$new)
->with('updated',$updated);
} }
private function set_oc_schema(Collection $tv): void private function set_oc_schema(Collection $tv): void

View File

@ -7,6 +7,7 @@ use Illuminate\Support\Arr;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use App\Classes\LDAP\Attribute; use App\Classes\LDAP\Attribute;
use App\Ldap\Entry;
use App\Traits\MD5Updates; use App\Traits\MD5Updates;
/** /**
@ -78,13 +79,14 @@ final class Password extends Attribute
return ($helpers=static::helpers())->has($id) ? new ($helpers->get($id)) : NULL; return ($helpers=static::helpers())->has($id) ? new ($helpers->get($id)) : NULL;
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
return view('components.attribute.password') return view('components.attribute.password')
->with('o',$this) ->with('o',$this)
->with('edit',$edit) ->with('edit',$edit)
->with('old',$old) ->with('old',$old)
->with('new',$new) ->with('new',$new)
->with('updated',$updated)
->with('helpers',static::helpers()->map(fn($item,$key)=>['id'=>$key,'value'=>$key])->sort()); ->with('helpers',static::helpers()->map(fn($item,$key)=>['id'=>$key,'value'=>$key])->sort());
} }

View File

@ -6,6 +6,7 @@ use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use App\Classes\LDAP\Attribute; use App\Classes\LDAP\Attribute;
use App\Ldap\Entry;
/** /**
* Represents the RDN for an Entry * Represents the RDN for an Entry
@ -31,7 +32,7 @@ final class RDN extends Attribute
]); ]);
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
return view('components.attribute.rdn') return view('components.attribute.rdn')
->with('o',$this); ->with('o',$this);

View File

@ -7,6 +7,7 @@ use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use App\Classes\LDAP\Attribute; use App\Classes\LDAP\Attribute;
use App\Ldap\Entry;
/** /**
* Represents an attribute whose values are schema related * Represents an attribute whose values are schema related
@ -53,7 +54,7 @@ abstract class Schema extends Attribute
__('No description available, can you help with one?')); __('No description available, can you help with one?'));
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
// @note Schema attributes cannot be edited // @note Schema attributes cannot be edited
return view('components.attribute.internal') return view('components.attribute.internal')

View File

@ -5,13 +5,14 @@ namespace App\Classes\LDAP\Attribute\Schema;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use App\Classes\LDAP\Attribute\Schema; use App\Classes\LDAP\Attribute\Schema;
use App\Ldap\Entry;
/** /**
* Represents a Generic Schema Attribute * Represents a Generic Schema Attribute
*/ */
class Generic extends Schema class Generic extends Schema
{ {
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
// @note Schema attributes cannot be edited // @note Schema attributes cannot be edited
return view('components.attribute.schema.generic') return view('components.attribute.schema.generic')

View File

@ -5,6 +5,7 @@ namespace App\Classes\LDAP\Attribute\Schema;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use App\Classes\LDAP\Attribute\Schema; use App\Classes\LDAP\Attribute\Schema;
use App\Ldap\Entry;
/** /**
* Represents a Mechanisms Attribute * Represents a Mechanisms Attribute
@ -33,7 +34,7 @@ final class Mechanisms extends Schema
return parent::_get(config_path('ldap_supported_saslmechanisms.txt'),$string,$key); return parent::_get(config_path('ldap_supported_saslmechanisms.txt'),$string,$key);
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
// @note Schema attributes cannot be edited // @note Schema attributes cannot be edited
return view('components.attribute.schema.mechanisms') return view('components.attribute.schema.mechanisms')

View File

@ -5,6 +5,7 @@ namespace App\Classes\LDAP\Attribute\Schema;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use App\Classes\LDAP\Attribute\Schema; use App\Classes\LDAP\Attribute\Schema;
use App\Ldap\Entry;
/** /**
* Represents an OID Attribute * Represents an OID Attribute
@ -34,7 +35,7 @@ final class OID extends Schema
return parent::_get(config_path('ldap_supported_oids.txt'),$string,$key); return parent::_get(config_path('ldap_supported_oids.txt'),$string,$key);
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View
{ {
// @note Schema attributes cannot be edited // @note Schema attributes cannot be edited
return view('components.attribute.schema.oid') return view('components.attribute.schema.oid')

View File

@ -22,7 +22,6 @@ use App\Exceptions\Import\{GeneralException,VersionException};
use App\Exceptions\InvalidUsage; use App\Exceptions\InvalidUsage;
use App\Http\Requests\{EntryRequest,EntryAddRequest,ImportRequest}; use App\Http\Requests\{EntryRequest,EntryAddRequest,ImportRequest};
use App\Ldap\Entry; use App\Ldap\Entry;
use App\View\Components\AttributeType;
class HomeController extends Controller class HomeController extends Controller
{ {
@ -90,15 +89,20 @@ class HomeController extends Controller
$xx->index = 0; $xx->index = 0;
$dn = $request->dn ? Crypt::decrypt($request->dn) : ''; $dn = $request->dn ? Crypt::decrypt($request->dn) : '';
$o = Factory::create(dn: $dn,attribute: $id,values: [],oc: $request->objectclasses);
return $request->noheader $view = $request->noheader
? view(sprintf('components.attribute.widget.%s',$id)) ? view(sprintf('components.attribute.widget.%s',$id))
->with('o',Factory::create(dn: $dn,attribute: $id,values: [],oc: $request->objectclasses))
->with('value',$request->value) ->with('value',$request->value)
->with('langtag',Entry::TAG_NOTAG)
->with('loop',$xx) ->with('loop',$xx)
: new AttributeType(Factory::create($dn,$id,[],$request->objectclasses),new: TRUE,edit: TRUE) : view('components.attribute-type')
->render(); ->with('new',TRUE)
->with('edit',TRUE);
return $view
->with('o',$o)
->with('langtag',Entry::TAG_NOTAG)
->with('updated',FALSE);
} }
public function entry_create(EntryAddRequest $request): \Illuminate\Http\RedirectResponse public function entry_create(EntryAddRequest $request): \Illuminate\Http\RedirectResponse
@ -350,7 +354,8 @@ class HomeController extends Controller
return Redirect::to('/') return Redirect::to('/')
->withInput() ->withInput()
->with('updated',collect($dirty)->map(fn($item,$key)=>$o->getObject(collect(explode(';',$key))->first()))); ->with('updated',collect($dirty)
->map(fn($item,$key)=>$o->getObject(collect(explode(';',$key))->first())));
} }
/** /**

View File

@ -12,7 +12,8 @@ trait MD5Updates
public function isDirty(): bool public function isDirty(): bool
{ {
foreach ($this->values_old->dot()->keys()->merge($this->values->dot()->keys())->unique() as $dotkey) foreach ($this->values_old->dot()->keys()->merge($this->values->dot()->keys())->unique() as $dotkey)
if (md5(Arr::get($this->values_old->dot(),$dotkey)) !== Arr::get($this->values->dot(),$dotkey)) if ((Arr::get($this->values_old->dot(),$dotkey) !== Arr::get($this->values->dot(),$dotkey))
&& (md5(Arr::get($this->values_old->dot(),$dotkey)) !== Arr::get($this->values->dot(),$dotkey)))
return TRUE; return TRUE;
return FALSE; return FALSE;

View File

@ -2,7 +2,6 @@
namespace App\View\Components; namespace App\View\Components;
use Closure;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use Illuminate\View\Component; use Illuminate\View\Component;
@ -16,19 +15,18 @@ class Attribute extends Component
public bool $new; public bool $new;
public bool $old; public bool $old;
public string $langtag; public string $langtag;
public ?string $na; // Text to render if the LDAPAttribute is null
/** /**
* Create a new component instance. * Create a new component instance.
*/ */
public function __construct(?LDAPAttribute $o,bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,?string $na=NULL) public function __construct(?LDAPAttribute $o,bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE)
{ {
$this->o = $o; $this->o = $o;
$this->edit = $edit; $this->edit = $edit;
$this->old = $old; $this->old = $old;
$this->new = $new; $this->new = $new;
$this->langtag = $langtag; $this->langtag = $langtag;
$this->na = $na; $this->updated = $updated;
} }
/** /**
@ -40,7 +38,7 @@ class Attribute extends Component
{ {
return $this->o return $this->o
? $this->o ? $this->o
->render(edit: $this->edit,old: $this->old,new: $this->new) ->render(edit: $this->edit,old: $this->old,new: $this->new,langtag: $this->langtag,updated: $this->updated)
: $this->na; : __('Unknown');
} }
} }

View File

@ -1,40 +0,0 @@
<?php
namespace App\View\Components;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
use App\Classes\LDAP\Attribute as LDAPAttribute;
use App\Ldap\Entry;
class AttributeType extends Component
{
private LDAPAttribute $o;
private bool $new;
private bool $edit;
private string $langtag;
/**
* Create a new component instance.
*/
public function __construct(LDAPAttribute $o,bool $new=FALSE,bool $edit=FALSE,string $langtag=Entry::TAG_NOTAG)
{
$this->o = $o;
$this->new = $new;
$this->edit = $edit;
$this->langtag = $langtag;
}
/**
* Get the view / contents that represent the component.
*/
public function render(): View
{
return view('components.attribute-type')
->with('o',$this->o)
->with('new',$this->new)
->with('edit',$this->edit)
->with('langtag',$this->langtag);
}
}

View File

@ -1 +1 @@
v2.1.1-rel v2.1.2-dev

13
public/css/custom.css vendored
View File

@ -23,6 +23,10 @@ input.form-control.input-group-end {
border-top-right-radius: 4px !important; border-top-right-radius: 4px !important;
} }
.custom-tooltip-success {
--bs-tooltip-bg: var(--bs-success);
}
.custom-tooltip-warning { .custom-tooltip-warning {
--bs-tooltip-bg: var(--bs-warning); --bs-tooltip-bg: var(--bs-warning);
--bs-tooltip-color: black; --bs-tooltip-color: black;
@ -69,4 +73,13 @@ input.form-control.input-group-end {
/* hide the site icons when the search is opened */ /* hide the site icons when the search is opened */
.search-wrapper.active + .header-menu.nav { .search-wrapper.active + .header-menu.nav {
display: none; display: none;
}
.page-title-wrapper .page-title-items {
margin-left: auto;
max-width: 50%;
}
.page-title-wrapper .page-title-items .page-title-status .alert {
font-size: 0.80em;
} }

View File

@ -13,8 +13,14 @@
</div> </div>
</div> </div>
<div class="page-title-actions"> <div class="page-title-items">
@yield('page_actions') <div class="page-title-actions">
@yield('page_actions')
</div>
<div class="page-title-status pt-4">
@yield('page_status')
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,4 +1,3 @@
<!-- $o=AttributeType::class -->
<div class="row pb-3"> <div class="row pb-3">
<div class="col-12 col-sm-1 col-md-2"></div> <div class="col-12 col-sm-1 col-md-2"></div>
<div class="col-12 col-sm-10 col-md-8"> <div class="col-12 col-sm-10 col-md-8">
@ -6,6 +5,9 @@
<div class="col-12 bg-light text-dark p-2"> <div class="col-12 bg-light text-dark p-2">
<strong><abbr title="{{ $o->description }}">{{ $o->name }}</abbr></strong> <strong><abbr title="{{ $o->description }}">{{ $o->name }}</abbr></strong>
<!-- Attribute Hints --> <!-- Attribute Hints -->
@if($updated)
<span class="float-end small text-success ms-2" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip-success" title="@lang('Updated')"><i class="fas fa-fw fa-marker"></i> </span>
@endif
<span class="float-end small"> <span class="float-end small">
@foreach($o->hints as $name => $description) @foreach($o->hints as $name => $description)
@if ($loop->index),@endif @if ($loop->index),@endif
@ -15,7 +17,7 @@
</div> </div>
</div> </div>
<x-attribute :o="$o" :edit="$edit" :new="$new" :langtag="$langtag"/> <x-attribute :o="$o" :edit="$edit" :new="$new" :langtag="$langtag" :updated="$updated"/>
</div> </div>
</div> </div>

View File

@ -1,10 +1,12 @@
@use(App\Ldap\Entry)
<!-- $o=Attribute::class --> <!-- $o=Attribute::class -->
<x-attribute.layout :edit="$edit" :new="$new" :o="$o"> <x-attribute.layout :edit="$edit=($edit ?? FALSE)" :new="$new=($new ?? FALSE)" :o="$o">
<div class="col-12"> <div class="col-12">
@foreach(Arr::get(old($o->name_lc,[$langtag=>$new ? [NULL] : $o->tagValues($langtag)]),$langtag,[]) as $key => $value) @foreach(Arr::get(old($o->name_lc,[($langtag=($langtag ?? Entry::TAG_NOTAG))=>$new ? [NULL] : $o->tagValues($langtag)]),$langtag,[]) as $key => $value)
@if($edit && (! $o->is_rdn)) @if($edit && (! $o->is_rdn))
<div class="input-group has-validation"> <div class="input-group has-validation">
<input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! ($tv=$o->tagValuesOld($langtag))->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ ! is_null($x=$tv->get($loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! $new) @disabled($o->isDynamic())> <input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! ($tv=$o->tagValuesOld($langtag))->contains($value),'bg-success-subtle'=>$updated]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ ! is_null($x=$tv->get($loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! $new) @disabled($o->isDynamic())>
<div class="invalid-feedback pb-2"> <div class="invalid-feedback pb-2">
@if($e) @if($e)
@ -14,7 +16,7 @@
</div> </div>
@else @else
<input type="text" class="form-control mb-1" value="{{ $value }}" disabled> <input type="text" @class(['form-control','mb-1','bg-success-subtle'=>$updated]) value="{{ $value }}" disabled>
@endif @endif
@endforeach @endforeach
</div> </div>

View File

@ -9,7 +9,7 @@
@default @default
<td> <td>
<input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}"> <input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}">
<img alt="{{ $o->dn }}" @class(['border','rounded','p-2','m-0','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index))]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" /> <img alt="{{ $o->dn }}" @class(['border','rounded','p-2','m-0','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'bg-success-subtle'=>$updated]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" />
@if($edit) @if($edit)
<br> <br>

View File

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

View File

@ -1,5 +1,5 @@
<div class="row pt-2"> <div class="row pt-2">
<div @class(['col-1','d-none'=>(! $edit) && (! ($detail ?? false))])></div> <div @class(['col-1','d-none'=>(! $edit) && (! ($detail ?? FALSE))])></div>
<div class="col-10"> <div class="col-10">
<attribute id="{{ $o->name }}"> <attribute id="{{ $o->name }}">
{{ $slot }} {{ $slot }}

View File

@ -2,7 +2,7 @@
<x-attribute.layout :edit="$edit" :new="$new" :o="$o" :langtag="$langtag"> <x-attribute.layout :edit="$edit" :new="$new" :o="$o" :langtag="$langtag">
@foreach(Arr::get(old($o->name_lc,[$langtag=>$new ? [NULL] : $o->tagValues($langtag)]),$langtag,[]) as $key => $value) @foreach(Arr::get(old($o->name_lc,[$langtag=>$new ? [NULL] : $o->tagValues($langtag)]),$langtag,[]) as $key => $value)
@if($edit) @if($edit)
<x-attribute.widget.objectclass :o="$o" :edit="$edit" :new="$new" :loop="$loop" :value="$value" :langtag="$langtag"/> <x-attribute.widget.objectclass :o="$o" :edit="$edit" :new="$new" :langtag="$langtag" :updated="$updated" :value="$value" :loop="$loop" />
@else @else
{{ $o->render_item_old($key) }} {{ $o->render_item_old($key) }}
@if ($o->isStructural($value)) @if ($o->isStructural($value))

View File

@ -5,7 +5,7 @@
@if($edit) @if($edit)
<div class="input-group has-validation mb-3"> <div class="input-group has-validation mb-3">
<x-form.select id="userpassword_hash_{{$loop->index}}" name="userpassword_hash[{{ $langtag }}][]" :value="$o->hash($value)->id()" :options="$helpers" allowclear="false" :disabled="true"/> <x-form.select id="userpassword_hash_{{$loop->index}}" name="userpassword_hash[{{ $langtag }}][]" :value="$o->hash($value)->id()" :options="$helpers" allowclear="false" :disabled="true"/>
<input type="password" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}" @readonly(true)> <input type="password" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value),'bg-success-subtle'=>$updated]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}" @readonly(true)>
<div class="invalid-feedback pb-2"> <div class="invalid-feedback pb-2">
@if($e) @if($e)

View File

@ -1,7 +1,7 @@
<span id="objectclass_{{$value}}"> <span id="objectclass_{{$value}}">
<div class="input-group has-validation"> <div class="input-group has-validation">
<!-- @todo Have an "x" to remove the entry, we need an event to process the removal, removing any attribute values along the way --> <!-- @todo Have an "x" to remove the entry, we need an event to process the removal, removing any attribute values along the way -->
<input type="text" @class(['form-control','input-group-end','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ Arr::get($o->values,$loop->index,'['.__('NEW').']') }}" @readonly(true)> <input type="text" @class(['form-control','input-group-end','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value),'bg-success-subtle'=>$updated]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ Arr::get($o->values,$loop->index,'['.__('NEW').']') }}" @readonly(true)>
@if ($o->isStructural($value)) @if ($o->isStructural($value))
<span class="input-group-end text-black-50">@lang('structural')</span> <span class="input-group-end text-black-50">@lang('structural')</span>
@else @else

View File

@ -2,6 +2,7 @@
@use(App\Classes\LDAP\Attribute\CertificateList) @use(App\Classes\LDAP\Attribute\CertificateList)
@use(App\Classes\LDAP\Attribute\Binary\JpegPhoto) @use(App\Classes\LDAP\Attribute\Binary\JpegPhoto)
@use(App\Classes\LDAP\Attribute\ObjectClass) @use(App\Classes\LDAP\Attribute\ObjectClass)
@php($clone=FALSE) @php($clone=FALSE)
<span class="p-0 m-0"> <span class="p-0 m-0">
@if($o->is_rdn) @if($o->is_rdn)

View File

@ -1,11 +1,5 @@
@if($errors->any()) @if($errors->any())
<div class="alert alert-danger"> <div class="alert alert-danger p-2">
<h4 class="alert-heading"><i class="fas fa-fw fa-thumbs-down"></i> Error?</h4> <p class="m-0"><i class="fas fa-fw fa-thumbs-down"></i> @lang('Validation Errors')</p>
<hr>
<ul style="list-style-type: square;">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div> </div>
@endif @endif

View File

@ -1,7 +1,5 @@
@if(session()->has('note')) @if(session()->has('note'))
<div class="alert alert-info"> <div class="alert alert-info p-2">
<h4 class="alert-heading"><i class="fas fa-fw fa-note-sticky"></i> Note:</h4> <p class="m-0"><i class="fas fa-fw fa-info"></i> {{ session()->pull('note') }}</p>
<hr>
<p>{{ session()->pull('note') }}</p>
</div> </div>
@endif @endif

View File

@ -1,12 +1,5 @@
@if(session()->has('updated')) @if(session()->has('updated'))
<div class="alert alert-success"> <div class="alert alert-success p-2">
<h4 class="alert-heading"><i class="fas fa-fw fa-thumbs-up"></i> Success!</h4> <p class="m-0"><i class="fas fa-fw fa-pen-to-square"></i> @lang('Entry updated') [{{ session()->get('updated')->count() }} @lang('attributes(s)')]</p>
<hr>
<p>{{ __('Entry updated') }}</p>
<ul style="list-style-type: square;">
@foreach (session()->pull('updated') as $key => $o)
<li><abbr title="{{ $o->description }}">{{ $o->name }}</abbr>: {{ $o->values->dot()->filter()->join(',') }}</li>
@endforeach
</ul>
</div> </div>
@endif @endif

View File

@ -11,19 +11,19 @@
<tr class="mt-1"> <tr class="mt-1">
<td class="p-0 pe-2">Created</td> <td class="p-0 pe-2">Created</td>
<th class="p-0"> <th class="p-0">
<x-attribute :o="$o->getObject('createtimestamp')" :na="__('Unknown')"/> [<x-attribute :o="$o->getObject('creatorsname')" :na="__('Unknown')"/>] <x-attribute :o="$o->getObject('createtimestamp')"/> [<x-attribute :o="$o->getObject('creatorsname')"/>]
</th> </th>
</tr> </tr>
<tr class="mt-1"> <tr class="mt-1">
<td class="p-0 pe-2">Modified</td> <td class="p-0 pe-2">Modified</td>
<th class="p-0"> <th class="p-0">
<x-attribute :o="$o->getObject('modifytimestamp')" :na="__('Unknown')"/> [<x-attribute :o="$o->getObject('modifiersname')" :na="__('Unknown')"/>] <x-attribute :o="$o->getObject('modifytimestamp')"/> [<x-attribute :o="$o->getObject('modifiersname')"/>]
</th> </th>
</tr> </tr>
<tr class="mt-1"> <tr class="mt-1">
<td class="p-0 pe-2">UUID</td> <td class="p-0 pe-2">UUID</td>
<th class="p-0"> <th class="p-0">
<x-attribute :o="$o->getObject('entryuuid')" :na="__('Unknown')"/> <x-attribute :o="$o->getObject('entryuuid')""/>
</th> </th>
</tr> </tr>
@if($langtags->count()) @if($langtags->count())

View File

@ -9,9 +9,11 @@
]) ])
@endsection @endsection
@section('main-content') @section('page_status')
<x-error/> <x-error/>
@endsection
@section('main-content')
<div class="row"> <div class="row">
<div class="offset-1 col-10"> <div class="offset-1 col-10">
<div class="main-card mb-3 card"> <div class="main-card mb-3 card">

View File

@ -51,27 +51,25 @@
</div> </div>
</div> </div>
</div> </div>
@endsection
<div class="row"> @section('page_status')
<div class="col"> @if(($x=$o->getOtherTags()->filter(fn($item)=>$item->diff(['binary'])->count()))->count())
@if(($x=$o->getOtherTags()->filter(fn($item)=>$item->diff(['binary'])->count()))->count()) <div class="alert alert-danger p-2">
<div class="ms-4 mt-4 alert alert-danger p-2" style="max-width: 30em; font-size: 0.80em;"> This entry has [<strong>{!! $x->flatten()->join('</strong>, <strong>') !!}</strong>] tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those tags with an LDIF import.
This entry has [<strong>{!! $x->flatten()->join('</strong>, <strong>') !!}</strong>] tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those tags with an LDIF import.
</div>
@elseif(($x=$o->getLangMultiTags())->count())
<div class="ms-4 mt-4 alert alert-danger p-2" style="max-width: 30em; font-size: 0.80em;">
This entry has multi-language tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those lang tags with an LDIF import.
</div>
@endif
</div> </div>
</div> @elseif(($x=$o->getLangMultiTags())->count())
<div class="alert alert-danger p-2">
This entry has multi-language tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those lang tags with an LDIF import.
</div>
@endif
<x-note/>
<x-error/>
<x-updated/>
@endsection @endsection
@section('main-content') @section('main-content')
<x-note/>
<x-updated/>
<x-error/>
<div class="main-card mb-3 card"> <div class="main-card mb-3 card">
<div class="card-body"> <div class="card-body">
<div class="card-header-tabs"> <div class="card-header-tabs">
@ -113,12 +111,13 @@
<div class="card-body"> <div class="card-body">
<div class="tab-content"> <div class="tab-content">
@php($up=(session()->pull('updated') ?: collect()))
@foreach($langtags as $tag) @foreach($langtags as $tag)
<div class="tab-pane @if(! $loop->index) active @endif" id="tab-lang-{{ $tag ?: '_default' }}" role="tabpanel"> <div class="tab-pane @if(! $loop->index) active @endif" id="tab-lang-{{ $tag ?: '_default' }}" role="tabpanel">
@switch($tag) @switch($tag)
@case(Entry::TAG_NOTAG) @case(Entry::TAG_NOTAG)
@foreach ($o->getVisibleAttributes($tag) as $ao) @foreach ($o->getVisibleAttributes($tag) as $ao)
<x-attribute-type :edit="true" :o="$ao" :langtag="$tag"/> <x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :langtag="$tag" :updated="$up->contains($ao->name_lc)"/>
@endforeach @endforeach
@break @break
@ -131,7 +130,7 @@
@default @default
@foreach ($o->getVisibleAttributes($langtag=sprintf('lang-%s',$tag)) as $ao) @foreach ($o->getVisibleAttributes($langtag=sprintf('lang-%s',$tag)) as $ao)
<x-attribute-type :edit="true" :o="$ao" :langtag="$langtag"/> <x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :langtag="$langtag" :updated="$up->contains($ao->name_lc)"/>
@endforeach @endforeach
@endswitch @endswitch
</div> </div>
@ -153,7 +152,7 @@
<!-- Internal Attributes --> <!-- Internal Attributes -->
<div class="tab-pane mt-3" id="internal" role="tabpanel"> <div class="tab-pane mt-3" id="internal" role="tabpanel">
@foreach ($o->getInternalAttributes() as $ao) @foreach ($o->getInternalAttributes() as $ao)
<x-attribute-type :o="$ao"/> <x-attribute-type :o="$ao" :edit="FALSE" :new="FALSE" :langtag="Entry::TAG_NOTAG" :updated="FALSE"/>
@endforeach @endforeach
</div> </div>
</div> </div>

View File

@ -9,11 +9,11 @@
]) ])
@endsection @endsection
@section('main-content') @section('page_status')
<x-note/>
<x-success/>
<x-error/> <x-error/>
@endsection
@section('main-content')
<div class="main-card mb-3 card"> <div class="main-card mb-3 card">
<form id="dn-update" method="POST" class="needs-validation" action="{{ url('entry/update/commit') }}" novalidate> <form id="dn-update" method="POST" class="needs-validation" action="{{ url('entry/update/commit') }}" novalidate>
@csrf @csrf