This commit is mainly as a result of creating DN entries and improves some backend functions:
* Enable creation of new entries, * Change all our ajax frames to go through /frames URI instead of /dn, * Add our frame command to the encrypted DN, * Automatically redirect to root URL when selecting a tree item and currently in another path (as a result of a prior POST activity), * Some validation improvements DNExists/HasStructuralObjectClass
This commit is contained in:
64
resources/views/components/attribute/rdn.blade.php
Normal file
64
resources/views/components/attribute/rdn.blade.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<!-- $o=RDN::class -->
|
||||
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o">
|
||||
@foreach($o->values as $value)
|
||||
@if($edit)
|
||||
<div class="input-group has-validation mb-3">
|
||||
<select class="form-select @error('rdn')is-invalid @enderror" id="rdn" name="rdn">
|
||||
<option value=""></option>
|
||||
|
||||
@foreach($o->attrs->map(fn($item)=>['id'=>$item,'value'=>$item]) as $option)
|
||||
@continue(! Arr::get($option,'value'))
|
||||
<option value="{{ Arr::get($option,'id') }}" @selected(Arr::get($option,'id') == old('rdn',$value ?? ''))>{{ Arr::get($option,'value') }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="input-group-text">=</span>
|
||||
<input type="text" @class(['form-control','is-invalid'=>$errors->get('rdn_value')]) id="rdn_value" name="rdn_value" value="{{ old('rdn_value') }}" placeholder="rdn">
|
||||
<label class="input-group-text" for="inputGroupSelect02">,{{ $o->base }}</label>
|
||||
|
||||
<div class="invalid-feedback pb-2">
|
||||
@error('rdn')
|
||||
{{ $message }}
|
||||
@enderror
|
||||
@error('rdn_value')
|
||||
{{ $message }}
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
{{ $value }}
|
||||
@endif
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
||||
|
||||
@section('page-scripts')
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
var rdn_value_set = null;
|
||||
var rdn_attr = null;
|
||||
|
||||
function set_rdn_value() {
|
||||
if (rdn_attr && rdn_value_set)
|
||||
$('#'+rdn_attr).find('input').val($('input#rdn_value').val());
|
||||
}
|
||||
|
||||
$('select#rdn').on('change',function() {
|
||||
// if rdn_attr is already set (and its now different), remove read only and clear value
|
||||
if (rdn_attr)
|
||||
$('#'+rdn_attr).find('input').attr('readonly',false).val('');
|
||||
|
||||
// set RDN attribute read-only
|
||||
if (rdn_attr = $(this).val())
|
||||
$('#'+rdn_attr).find('input').attr('readonly',true).val('');
|
||||
|
||||
set_rdn_value();
|
||||
})
|
||||
|
||||
$('input#rdn_value').on('change',function() {
|
||||
rdn_value_set = $(this).val();
|
||||
|
||||
set_rdn_value();
|
||||
})
|
||||
});
|
||||
</script>
|
||||
@endsection
|
@@ -46,12 +46,15 @@
|
||||
if (! rendered)
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
// @todo When this is opened a second time, the data is appended.
|
||||
cache: false,
|
||||
url: '{{ url('entry/objectclass/add') }}',
|
||||
data: {
|
||||
oc: oc,
|
||||
},
|
||||
success: function(data) {
|
||||
$('select#newoc').select2({
|
||||
dropdownParent: $('#new_objectclass-modal'),
|
||||
theme: 'bootstrap-5',
|
||||
allowClear: true,
|
||||
multiple: true,
|
||||
data: data,
|
||||
});
|
||||
@@ -60,8 +63,6 @@
|
||||
if (e.status != 412)
|
||||
alert('That didnt work? Please try again....');
|
||||
},
|
||||
url: '{{ url('entry/objectclass/add') }}/'+dn,
|
||||
cache: false
|
||||
});
|
||||
|
||||
rendered = true;
|
||||
|
@@ -15,7 +15,7 @@
|
||||
{{ $slot }}
|
||||
@isset($name)
|
||||
<span class="invalid-feedback">
|
||||
@error((! empty($old)) ? $old : $name)
|
||||
@error((! empty($old)) ? $old : ($id ?? $name))
|
||||
{{ $message }}
|
||||
@elseif(isset($feedback))
|
||||
{{ $feedback }}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
@isset($name)
|
||||
<input type="hidden" id="{{ $id ?? $name }}_disabled" name="{{ $name }}" value="" disabled>
|
||||
@endisset
|
||||
<select 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)>
|
||||
<select class="form-select @isset($name)@error((! empty($old)) ? $old : ($id ?? $name)) is-invalid @enderror @endisset" id="{{ $id ?? $name }}" @isset($name)name="{{ $name }}"@endisset @required(isset($required) && $required) @disabled(isset($disabled) && $disabled)>
|
||||
@if((empty($value) && ! empty($options)) || isset($addnew) || isset($choose))
|
||||
<option value=""></option>
|
||||
@isset($addnew)
|
||||
@@ -54,10 +54,24 @@
|
||||
width: 'style',
|
||||
allowClear: {{ $allowclear ?? 'false' }},
|
||||
placeholder: '{{ $placeholder ?? '' }}',
|
||||
multiple: {{ $multiple ?? 'false' }},
|
||||
@isset($addvalues)
|
||||
tags: true,
|
||||
@endisset
|
||||
});
|
||||
|
||||
@if(isset($multiple) && (! $multiple))
|
||||
$('#{{ $id ?? $name }}').val(' ');
|
||||
$('#{{ $id ?? $name }}').trigger('change');
|
||||
@endif
|
||||
|
||||
@isset($options)
|
||||
@if($options->count() === 1)
|
||||
$('#{{ $id ?? $name }}')
|
||||
.val('{{ $options->first()['id'] }}')
|
||||
.trigger("change")
|
||||
@endif
|
||||
@endisset
|
||||
});
|
||||
</script>
|
||||
@append
|
22
resources/views/fragment/dn/add_attr.blade.php
Normal file
22
resources/views/fragment/dn/add_attr.blade.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<div id="newattrs"></div>
|
||||
|
||||
<!-- Add new attributes -->
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-1 col-md-2"></div>
|
||||
<div class="col-12 col-sm-10 col-md-8">
|
||||
<div class="d-none" id="newattr-select">
|
||||
<div class="row">
|
||||
<div class="col-12 bg-dark text-light p-2">
|
||||
<i class="fas fa-plus-circle"></i> Add New Attribute
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 pt-2">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2"></div>
|
||||
</div>
|
@@ -3,7 +3,7 @@
|
||||
<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>
|
||||
<td class="text-end align-text-top p-0 {{ $x ? 'ps-5' : 'pt-2' }}"><strong>{{ $o->getDn() }}</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="line-height-1" style="font-size: 55%;vertical-align: bottom;" colspan="2">
|
||||
|
123
resources/views/frames/create.blade.php
Normal file
123
resources/views/frames/create.blade.php
Normal file
@@ -0,0 +1,123 @@
|
||||
@extends('layouts.dn')
|
||||
|
||||
@section('page_title')
|
||||
@include('fragment.dn.header',['o'=>($oo=config('server')->fetch(old('container',$container)))])
|
||||
@endsection
|
||||
|
||||
@section('main-content')
|
||||
<div class="row">
|
||||
<div class="offset-1 col-10">
|
||||
<div class="main-card mb-3 card">
|
||||
|
||||
<div class="card-header">
|
||||
@lang('Create New Entry') - @lang('Step') {{ $step }}
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form id="dn-create" method="POST" class="needs-validation" action="{{ url((int)$step === 2 ? 'entry/create' : 'entry/add') }}" enctype="multipart/form-data" novalidate>
|
||||
@csrf
|
||||
|
||||
<input type="hidden" name="key" value="{{ Crypt::encryptString('*create|'.$container) }}">
|
||||
@if($step < 2)
|
||||
<input type="hidden" name="step" value="{{ $step }}">
|
||||
@endif
|
||||
|
||||
@switch($step)
|
||||
@case(1)
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6">
|
||||
<x-form.select
|
||||
id="objectclass"
|
||||
name="objectclass[]"
|
||||
:label="__('Select a Structural ObjectClass...')"
|
||||
:options="($oc=config('server')->schema('objectclasses'))
|
||||
->filter(fn($item)=>$item->isStructural())
|
||||
->sortBy(fn($item)=>$item->name_lc)
|
||||
->map(fn($item)=>['id'=>$item->name,'value'=>$item->name])"
|
||||
multiple="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@break
|
||||
|
||||
@case(2)
|
||||
<x-attribute-type :edit="true" :o="$o->getObject('rdn')"/>
|
||||
|
||||
@foreach ($o->getVisibleAttributes() as $ao)
|
||||
<x-attribute-type :edit="true" :o="$ao"/>
|
||||
@endforeach
|
||||
|
||||
@include('fragment.dn.add_attr')
|
||||
|
||||
@break;
|
||||
@endswitch
|
||||
</form>
|
||||
|
||||
<div class="row d-none pt-3">
|
||||
<div class="col-12 {{ $step > 1 ? 'offset-sm-2' : '' }} col-sm-4 col-lg-2">
|
||||
<x-form.reset form="dn-create"/>
|
||||
<x-form.submit action="Next" form="dn-create"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('page-scripts')
|
||||
<script type="text/javascript">
|
||||
var oc = {!! $oo->getObject('objectclass')->values !!};
|
||||
|
||||
function editmode() {
|
||||
// Find all input items and turn off readonly
|
||||
$('input.form-control').each(function() {
|
||||
// Except for objectClass - @todo show an "X" instead
|
||||
if ($(this)[0].name.match(/^objectclass/))
|
||||
return;
|
||||
|
||||
$(this).attr('readonly',false);
|
||||
});
|
||||
|
||||
// Our password type
|
||||
$('div#userPassword .form-select').each(function() {
|
||||
$(this).prop('disabled',false);
|
||||
})
|
||||
|
||||
$('.row.d-none').removeClass('d-none');
|
||||
$('.addable.d-none').removeClass('d-none');
|
||||
$('.deletable.d-none').removeClass('d-none');
|
||||
$('#newattr-select.d-none').removeClass('d-none');
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#newattr').on('change',function(item) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
beforeSend: function() {},
|
||||
success: function(data) {
|
||||
$('#newattrs').append(data);
|
||||
},
|
||||
error: function(e) {
|
||||
if (e.status != 412)
|
||||
alert('That didnt work? Please try again....');
|
||||
},
|
||||
url: '{{ url('entry/attr/add') }}/'+item.target.value,
|
||||
data: {
|
||||
objectclasses: oc,
|
||||
},
|
||||
cache: false
|
||||
});
|
||||
|
||||
// Remove the option from the list
|
||||
$(this).find('[value="'+item.target.value+'"]').remove()
|
||||
|
||||
// If there are no more options
|
||||
if ($(this).find("option").length === 1)
|
||||
$('#newattr-select').remove();
|
||||
});
|
||||
|
||||
editmode();
|
||||
});
|
||||
</script>
|
||||
@append
|
@@ -1,7 +1,7 @@
|
||||
@extends('layouts.dn')
|
||||
|
||||
@section('page_title')
|
||||
@include('fragment.dn.header')
|
||||
@include('fragment.dn.header',['o'=>($o=config('server')->fetch($dn))])
|
||||
@endsection
|
||||
|
||||
@section('main-content')
|
||||
@@ -9,8 +9,6 @@
|
||||
<x-updated/>
|
||||
<x-error/>
|
||||
|
||||
<!-- @todo If we are redirected here, check old() and add back any attributes that were in the original submission -->
|
||||
|
||||
<div class="main-card mb-3 card">
|
||||
<div class="card-body">
|
||||
<div class="card-header-tabs">
|
||||
@@ -34,31 +32,7 @@
|
||||
<x-attribute-type :edit="true" :o="$ao"/>
|
||||
@endforeach
|
||||
|
||||
<div id="newattrs"></div>
|
||||
|
||||
<!-- Add new attributes -->
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-1 col-md-2"></div>
|
||||
<div class="col-12 col-sm-10 col-md-8">
|
||||
<div class="d-none" id="newattr-select">
|
||||
|
||||
@if($o->getMissingAttributes()->count())
|
||||
<div class="row">
|
||||
<div class="col-12 bg-dark text-light p-2">
|
||||
<i class="fas fa-plus-circle"></i> Add New Attribute
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 pt-2">
|
||||
<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
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2"></div>
|
||||
</div>
|
||||
@include('fragment.dn.add_attr')
|
||||
</form>
|
||||
|
||||
<div class="row d-none pt-3">
|
||||
|
@@ -15,7 +15,7 @@
|
||||
<div class="main-card mb-3 card">
|
||||
<form id="import-form" action="{{ url('import/process/ldif') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<input type="hidden" name="frame" value="import">
|
||||
<input type="hidden" name="key" value="{{ Crypt::encryptString('*import|_NOP') }}">
|
||||
|
||||
<div class="card-header">
|
||||
@lang('LDIF Import')
|
||||
|
@@ -1,10 +1,11 @@
|
||||
@use(App\Classes\LDAP\Server)
|
||||
@extends('layouts.dn')
|
||||
|
||||
@section('page_title')
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td style="border-radius: 5px;"><div class="page-title-icon f32"><i class="fas fa-fingerprint"></i></div></td>
|
||||
<td class="top text-end align-text-top p-0 pt-2"><strong>{{ \App\Classes\LDAP\Server::schemaDN() }}</strong></td>
|
||||
<td class="top text-end align-text-top p-0 pt-2"><strong>{{ Server::schemaDN() }}</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
@endsection
|
||||
|
@@ -17,7 +17,7 @@
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-4">
|
||||
<h3 class="d-inline-block d-sm-none">phpLDAPadmin</h3>
|
||||
<img src="{{ url('/images/logo.png') }}" class="logo-image col-12" alt="PLA Logo">
|
||||
<img src="{{ url('images/logo.png') }}" class="logo-image col-12" alt="PLA Logo">
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-8">
|
||||
@@ -48,14 +48,23 @@
|
||||
var subpage = window.location.hash;
|
||||
|
||||
$(document).ready(function() {
|
||||
// Enable navigating to a page via a URL fragment, and that fragment is defined with a server-icon
|
||||
var valid = Object.values($('.server-icon > a').map(function(item) {
|
||||
return $(this).attr('id');
|
||||
})).indexOf(subpage.substring(1));
|
||||
if (subpage) {
|
||||
// Enable navigating to a page via a URL fragment, and that fragment is defined with a server-icon
|
||||
var valid = Object.values($('.server-icon > a').map(function() {
|
||||
return $(this).attr('id');
|
||||
})).indexOf(subpage.substring(1));
|
||||
|
||||
if (valid !== -1 && subpage) {
|
||||
// The click() event wont have been registered yet, so we need to delay us clicking it
|
||||
setTimeout(function() { $(subpage).click(); },250);
|
||||
if (valid !== -1) {
|
||||
// @todo this condition can probably be removed
|
||||
console.log('teleporting...:'+subpage.substring(1));
|
||||
// The click() event wont have been registered yet, so we need to delay us clicking it
|
||||
setTimeout(function() { $(subpage).click(); },250);
|
||||
|
||||
} else if (valid === -1) {
|
||||
// Clear the hash
|
||||
history.replaceState(null,null,' ');
|
||||
getNode(subpage.substring(1));
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
Reference in New Issue
Block a user