parent
1fbaf5fcbf
commit
a247db7e93
|
@ -886,6 +886,10 @@ json-tree .branch-preview {
|
|||
text-decoration-line: underline;
|
||||
}
|
||||
|
||||
reach-portal > div {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
input[style*='background-image: url("data:image/png'] + [data-cy='auth-passwordInputToggle'] {
|
||||
right: 20px;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
|
||||
--orange-1: #e86925;
|
||||
|
||||
--BE-only: var(--orange-1);
|
||||
--BE-only: var(--ui-warning-7);
|
||||
|
||||
/* Default Theme */
|
||||
--bg-card-color: var(--white-color);
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="76" height="75" viewBox="0 0 76 75" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect opacity="0.2" x="0.5" width="75" height="75" rx="37.5" fill="#713B12"/>
|
||||
<path d="M31.5353 36.1666V30.8333C31.5353 29.0652 32.2164 27.3695 33.4288 26.1192C34.6412 24.869 36.2855 24.1666 38 24.1666C39.7145 24.1666 41.3588 24.869 42.5712 26.1192C43.7835 27.3695 44.4646 29.0652 44.4646 30.8333V36.1666M28.9495 36.1666H47.0505C48.4786 36.1666 49.6364 37.3605 49.6364 38.8333V48.1666C49.6364 49.6394 48.4786 50.8333 47.0505 50.8333H28.9495C27.5214 50.8333 26.3636 49.6394 26.3636 48.1666V38.8333C26.3636 37.3605 27.5214 36.1666 28.9495 36.1666Z" stroke="#FEC84B" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 735 B |
|
@ -1,5 +1,5 @@
|
|||
<a class="ml-5 vertical-center" href="{{ $ctrl.url }}" target="_blank" rel="noopener" ng-if="$ctrl.limitedToBE">
|
||||
<ng-transclude></ng-transclude>
|
||||
<pr-icon icon="'briefcase'" feather="true" class="icon-primary"></pr-icon>
|
||||
<pr-icon icon="'briefcase'" feather="true" class-name="'icon icon-sm vertical-center'"></pr-icon>
|
||||
<span class="be-indicator-label">Business Edition Feature</span>
|
||||
</a>
|
||||
|
|
|
@ -20,14 +20,59 @@ button.limited-be.oauth-save-settings-button {
|
|||
ng-form.limited-be,
|
||||
form.limited-be,
|
||||
div.limited-be {
|
||||
border: solid 1px var(--BE-only);
|
||||
box-shadow: var(--shadow-boxselector-color);
|
||||
padding: 10px;
|
||||
border: solid 2px var(--BE-only);
|
||||
border-radius: 8px;
|
||||
pointer-events: none;
|
||||
touch-action: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.limited-be-content {
|
||||
background: rgba(247, 144, 9, 0.1);
|
||||
opacity: 0.5;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.limited-be-link {
|
||||
z-index: 5;
|
||||
position: relative;
|
||||
width: 270px;
|
||||
height: 40px;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
float: right;
|
||||
border-top-right-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
background-color: var(--ui-warning-5);
|
||||
color: var(--ui-warning-9);
|
||||
padding: 5px 10px;
|
||||
touch-action: auto;
|
||||
cursor: hand;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.limited-be-link a {
|
||||
cursor: hand;
|
||||
pointer-events: auto;
|
||||
color: var(--ui-warning-9);
|
||||
}
|
||||
|
||||
.limited-be-link a:hover {
|
||||
text-decoration: underline;
|
||||
color: var(--ui-warning-9);
|
||||
}
|
||||
|
||||
.overlay {
|
||||
background-image: url(../../assets/ico/lock.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.limited-be input,
|
||||
.limited-be .widget-body {
|
||||
background: rgba(247, 144, 9, 0.05);
|
||||
}
|
||||
|
||||
.form-control.limited-be[disabled] {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
|
|
@ -1,170 +1,176 @@
|
|||
<ng-form class="ad-settings" limited-feature-dir="{{::$ctrl.limitedFeatureId}}" limited-feature-class="limited-be">
|
||||
<be-feature-indicator feature="$ctrl.limitedFeatureId" class="my-8 block"></be-feature-indicator>
|
||||
<div class="overlay">
|
||||
<div class="limited-be-link vertical-center"
|
||||
><be-feature-indicator feature="$ctrl.limitedFeatureId"></be-feature-indicator
|
||||
><portainer-tooltip message="'This feature is currently limited to Business Edition users only. '"></portainer-tooltip
|
||||
></div>
|
||||
<div class="limited-be-content">
|
||||
<auto-user-provision-toggle ng-model="$ctrl.settings.AutoCreateUsers">
|
||||
<field-description>
|
||||
With automatic user provisioning enabled, Portainer will create user(s) automatically with standard user role and assign them to team(s) which matches to LDAP group
|
||||
name(s). If disabled, users must be created in Portainer beforehand.
|
||||
</field-description>
|
||||
</auto-user-provision-toggle>
|
||||
|
||||
<auto-user-provision-toggle ng-model="$ctrl.settings.AutoCreateUsers">
|
||||
<field-description>
|
||||
With automatic user provisioning enabled, Portainer will create user(s) automatically with standard user role and assign them to team(s) which matches to LDAP group name(s).
|
||||
If disabled, users must be created in Portainer beforehand.
|
||||
</field-description>
|
||||
</auto-user-provision-toggle>
|
||||
|
||||
<div>
|
||||
<div class="col-sm-12 form-section-title"> Information </div>
|
||||
<div class="form-group col-sm-12 text-muted small">
|
||||
When using Microsoft AD authentication, Portainer will delegate user authentication to the Domain Controller(s) configured below; if there is no connectivity, Portainer will
|
||||
fallback to internal authentication.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 form-section-title"> AD configuration </div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
You can configure multiple AD Controllers for authentication fallback. Make sure all servers are using the same configuration (i.e. if TLS is enabled, they should all use
|
||||
the same certificates).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ldap_url" class="col-sm-3 col-lg-2 control-label text-left" style="display: flex; flex-wrap: wrap">
|
||||
AD Controller
|
||||
<button
|
||||
type="button"
|
||||
class="label label-default interactive vertical-center"
|
||||
style="border: 0"
|
||||
ng-click="$ctrl.addLDAPUrl()"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
>
|
||||
<pr-icon icon="'plus-circle'" feather="true"></pr-icon>
|
||||
Add additional server
|
||||
</button>
|
||||
</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<div ng-repeat="url in $ctrl.settings.URLs track by $index" style="display: flex; margin-bottom: 10px">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ldap_url"
|
||||
ng-model="$ctrl.settings.URLs[$index]"
|
||||
placeholder="e.g. 10.0.0.10:389 or myldap.domain.tld:389"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
<button
|
||||
ng-if="$index > 0"
|
||||
class="btn btn-sm btn-danger"
|
||||
type="button"
|
||||
ng-click="$ctrl.removeLDAPUrl($index)"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" feather="true"></pr-icon>
|
||||
</button>
|
||||
<div>
|
||||
<div class="col-sm-12 form-section-title"> Information </div>
|
||||
<div class="form-group col-sm-12 text-muted small">
|
||||
When using Microsoft AD authentication, Portainer will delegate user authentication to the Domain Controller(s) configured below; if there is no connectivity, Portainer
|
||||
will fallback to internal authentication.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 form-section-title"> AD configuration </div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
You can configure multiple AD Controllers for authentication fallback. Make sure all servers are using the same configuration (i.e. if TLS is enabled, they should all
|
||||
use the same certificates).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ldap_url" class="col-sm-3 col-lg-2 control-label text-left" style="display: flex; flex-wrap: wrap">
|
||||
AD Controller
|
||||
<button
|
||||
type="button"
|
||||
class="label label-default interactive vertical-center"
|
||||
style="border: 0"
|
||||
ng-click="$ctrl.addLDAPUrl()"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
>
|
||||
<pr-icon icon="'plus-circle'" feather="true"></pr-icon>
|
||||
Add additional server
|
||||
</button>
|
||||
</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<div ng-repeat="url in $ctrl.settings.URLs track by $index" style="display: flex; margin-bottom: 10px">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ldap_url"
|
||||
ng-model="$ctrl.settings.URLs[$index]"
|
||||
placeholder="e.g. 10.0.0.10:389 or myldap.domain.tld:389"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
<button
|
||||
ng-if="$index > 0"
|
||||
class="btn btn-sm btn-danger"
|
||||
type="button"
|
||||
ng-click="$ctrl.removeLDAPUrl($index)"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ldap_username" class="col-sm-3 control-label text-left">
|
||||
Service Account
|
||||
<portainer-tooltip message="'Account that will be used to search for users.'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ldap_username"
|
||||
ng-model="$ctrl.settings.ReaderDN"
|
||||
placeholder="reader@domain.tld"
|
||||
ng-change="$ctrl.onAccountChange($ctrl.settings.ReaderDN)"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ldap_password" class="col-sm-3 control-label text-left">
|
||||
Service Account Password
|
||||
<portainer-tooltip message="'If you do not enter a password, Portainer will leave the current password unchanged.'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
type="password"
|
||||
class="form-control"
|
||||
id="ldap_password"
|
||||
ng-model="$ctrl.settings.Password"
|
||||
placeholder="password"
|
||||
autocomplete="new-password"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ldap-connectivity-check
|
||||
ng-if="!$ctrl.settings.TLSConfig.TLS && !$ctrl.settings.StartTLS"
|
||||
settings="$ctrl.settings"
|
||||
state="$ctrl.state"
|
||||
connectivity-check="$ctrl.connectivityCheck"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-connectivity-check>
|
||||
|
||||
<ldap-settings-security
|
||||
title="AD Connectivity Security"
|
||||
settings="$ctrl.settings"
|
||||
tlsca-cert="$ctrl.tlscaCert"
|
||||
upload-in-progress="$ctrl.state.uploadInProgress"
|
||||
on-tlsca-cert-change="($ctrl.onTlscaCertChange)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-settings-security>
|
||||
|
||||
<ldap-connectivity-check
|
||||
ng-if="$ctrl.settings.TLSConfig.TLS || $ctrl.settings.StartTLS"
|
||||
settings="$ctrl.settings"
|
||||
state="$ctrl.state"
|
||||
connectivity-check="$ctrl.connectivityCheck"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-connectivity-check>
|
||||
|
||||
<ldap-user-search
|
||||
style="margin-top: 5px"
|
||||
show-username-format="true"
|
||||
settings="$ctrl.settings.SearchSettings"
|
||||
domain-suffix="{{ $ctrl.domainSuffix }}"
|
||||
base-filter="(objectClass=user)"
|
||||
on-search-click="($ctrl.searchUsers)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-user-search>
|
||||
|
||||
<ldap-group-search
|
||||
style="margin-top: 5px"
|
||||
settings="$ctrl.settings.GroupSearchSettings"
|
||||
domain-suffix="{{ $ctrl.domainSuffix }}"
|
||||
base-filter="(objectClass=group)"
|
||||
on-search-click="($ctrl.searchGroups)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-group-search>
|
||||
|
||||
<ldap-custom-admin-group
|
||||
style="margin-top: 5px"
|
||||
settings="$ctrl.settings"
|
||||
on-search-click="($ctrl.onSearchAdminGroupsClick)"
|
||||
selected-admin-groups="$ctrl.selectedAdminGroups"
|
||||
default-admin-group-search-filter="'(objectClass=groupOfNames)'"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
is-limited-feature-self-contained="false"
|
||||
></ldap-custom-admin-group>
|
||||
|
||||
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId" is-limited-feature-self-contained="false"></ldap-settings-test-login>
|
||||
<save-auth-settings-button
|
||||
on-save-settings="($ctrl.onSaveSettings)"
|
||||
save-button-state="($ctrl.saveButtonState)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
save-button-disabled="($ctrl.isSaveSettingButtonDisabled())"
|
||||
></save-auth-settings-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ldap_username" class="col-sm-3 control-label text-left">
|
||||
Service Account
|
||||
<portainer-tooltip message="'Account that will be used to search for users.'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ldap_username"
|
||||
ng-model="$ctrl.settings.ReaderDN"
|
||||
placeholder="reader@domain.tld"
|
||||
ng-change="$ctrl.onAccountChange($ctrl.settings.ReaderDN)"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ldap_password" class="col-sm-3 control-label text-left">
|
||||
Service Account Password
|
||||
<portainer-tooltip message="'If you do not enter a password, Portainer will leave the current password unchanged.'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
type="password"
|
||||
class="form-control"
|
||||
id="ldap_password"
|
||||
ng-model="$ctrl.settings.Password"
|
||||
placeholder="password"
|
||||
autocomplete="new-password"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ldap-connectivity-check
|
||||
ng-if="!$ctrl.settings.TLSConfig.TLS && !$ctrl.settings.StartTLS"
|
||||
settings="$ctrl.settings"
|
||||
state="$ctrl.state"
|
||||
connectivity-check="$ctrl.connectivityCheck"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-connectivity-check>
|
||||
|
||||
<ldap-settings-security
|
||||
title="AD Connectivity Security"
|
||||
settings="$ctrl.settings"
|
||||
tlsca-cert="$ctrl.tlscaCert"
|
||||
upload-in-progress="$ctrl.state.uploadInProgress"
|
||||
on-tlsca-cert-change="($ctrl.onTlscaCertChange)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-settings-security>
|
||||
|
||||
<ldap-connectivity-check
|
||||
ng-if="$ctrl.settings.TLSConfig.TLS || $ctrl.settings.StartTLS"
|
||||
settings="$ctrl.settings"
|
||||
state="$ctrl.state"
|
||||
connectivity-check="$ctrl.connectivityCheck"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-connectivity-check>
|
||||
|
||||
<ldap-user-search
|
||||
style="margin-top: 5px"
|
||||
show-username-format="true"
|
||||
settings="$ctrl.settings.SearchSettings"
|
||||
domain-suffix="{{ $ctrl.domainSuffix }}"
|
||||
base-filter="(objectClass=user)"
|
||||
on-search-click="($ctrl.searchUsers)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-user-search>
|
||||
|
||||
<ldap-group-search
|
||||
style="margin-top: 5px"
|
||||
settings="$ctrl.settings.GroupSearchSettings"
|
||||
domain-suffix="{{ $ctrl.domainSuffix }}"
|
||||
base-filter="(objectClass=group)"
|
||||
on-search-click="($ctrl.searchGroups)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-group-search>
|
||||
|
||||
<ldap-custom-admin-group
|
||||
style="margin-top: 5px"
|
||||
settings="$ctrl.settings"
|
||||
on-search-click="($ctrl.onSearchAdminGroupsClick)"
|
||||
selected-admin-groups="$ctrl.selectedAdminGroups"
|
||||
default-admin-group-search-filter="'(objectClass=groupOfNames)'"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
is-limited-feature-self-contained="false"
|
||||
></ldap-custom-admin-group>
|
||||
|
||||
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId" is-limited-feature-self-contained="false"></ldap-settings-test-login>
|
||||
<save-auth-settings-button
|
||||
on-save-settings="($ctrl.onSaveSettings)"
|
||||
save-button-state="($ctrl.saveButtonState)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
save-button-disabled="($ctrl.isSaveSettingButtonDisabled())"
|
||||
></save-auth-settings-button>
|
||||
</ng-form>
|
||||
|
|
|
@ -1,184 +1,192 @@
|
|||
<ng-form limited-feature-dir="{{::$ctrl.limitedFeatureId}}" limited-feature-class="limited-be" class="ldap-settings-openldap">
|
||||
<be-feature-indicator feature="$ctrl.limitedFeatureId"></be-feature-indicator>
|
||||
|
||||
<div>
|
||||
<div class="col-sm-12 form-section-title"> Information </div>
|
||||
<div class="form-group col-sm-12 text-muted small">
|
||||
When using LDAP authentication, Portainer will delegate user authentication to a LDAP server and fallback to internal authentication if LDAP authentication fails.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 form-section-title"> LDAP configuration </div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
You can configure multiple LDAP Servers for authentication fallback. Make sure all servers are using the same configuration (i.e. if TLS is enabled, they should all use the
|
||||
same certificates).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ldap_url" class="col-sm-3 col-lg-2 control-label text-left" style="display: flex; flex-wrap: wrap">
|
||||
LDAP Server
|
||||
<button
|
||||
type="button"
|
||||
class="label label-default interactive vertical-center"
|
||||
style="border: 0"
|
||||
ng-click="$ctrl.addLDAPUrl()"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
>
|
||||
<pr-icon icon="'plus-circle'" feather="true"></pr-icon>
|
||||
Add additional server
|
||||
</button>
|
||||
</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<div ng-repeat="url in $ctrl.settings.URLs track by $index" style="display: flex; margin-bottom: 10px">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ldap_url"
|
||||
ng-model="$ctrl.settings.URLs[$index]"
|
||||
placeholder="e.g. 10.0.0.10:389 or myldap.domain.tld:389"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
<button
|
||||
ng-if="$index > 0"
|
||||
class="btn btn-sm btn-danger"
|
||||
type="button"
|
||||
ng-click="$ctrl.removeLDAPUrl($index)"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" feather="true" size="'md'"></pr-icon>
|
||||
</button>
|
||||
<div class="overlay">
|
||||
<div class="limited-be-link vertical-center"
|
||||
><be-feature-indicator feature="$ctrl.limitedFeatureId"></be-feature-indicator
|
||||
><portainer-tooltip message="'This feature is currently limited to Business Edition users only. '"></portainer-tooltip
|
||||
></div>
|
||||
<div class="limited-be-content">
|
||||
<div>
|
||||
<div class="col-sm-12 form-section-title"> Information </div>
|
||||
<div class="form-group col-sm-12 text-muted small">
|
||||
When using LDAP authentication, Portainer will delegate user authentication to a LDAP server and fallback to internal authentication if LDAP authentication fails.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Anonymous mode-->
|
||||
<div class="form-group">
|
||||
<label for="anonymous_mode" class="control-label text-left col-sm-3 col-lg-2">
|
||||
Anonymous mode
|
||||
<portainer-tooltip message="'Enable this option if the server is configured for Anonymous access.'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-12 form-section-title"> LDAP configuration </div>
|
||||
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="anonymous_mode" ng-model="$ctrl.settings.AnonymousMode" limited-feature-dir="{{::$ctrl.limitedFeatureId}}" limited-feature-tabindex="-1" />
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !Anonymous mode-->
|
||||
|
||||
<div ng-if="!$ctrl.settings.AnonymousMode">
|
||||
<div class="form-group">
|
||||
<label for="ldap_username" class="col-sm-3 col-lg-2 control-label text-left">
|
||||
Reader DN
|
||||
<portainer-tooltip message="'Account that will be used to search for users.'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ldap_username"
|
||||
ng-model="$ctrl.settings.ReaderDN"
|
||||
placeholder="cn=user,dc=domain,dc=tld"
|
||||
ng-change="$ctrl.onAccountChange($ctrl.settings.ReaderDN)"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
You can configure multiple LDAP Servers for authentication fallback. Make sure all servers are using the same configuration (i.e. if TLS is enabled, they should all use
|
||||
the same certificates).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ldap_password" class="col-sm-3 col-lg-2 control-label text-left">
|
||||
Password
|
||||
<portainer-tooltip message="'If you do not enter a password, Portainer will leave the current password unchanged.'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
type="password"
|
||||
class="form-control"
|
||||
id="ldap_password"
|
||||
ng-model="$ctrl.settings.Password"
|
||||
placeholder="password"
|
||||
autocomplete="new-password"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
<div class="form-group">
|
||||
<label for="ldap_url" class="col-sm-3 col-lg-2 control-label text-left" style="display: flex; flex-wrap: wrap">
|
||||
LDAP Server
|
||||
<button
|
||||
type="button"
|
||||
class="label label-default interactive vertical-center"
|
||||
style="border: 0"
|
||||
ng-click="$ctrl.addLDAPUrl()"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
>
|
||||
<pr-icon icon="'plus-circle'" feather="true"></pr-icon>
|
||||
Add additional server
|
||||
</button>
|
||||
</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<div ng-repeat="url in $ctrl.settings.URLs track by $index" style="display: flex; margin-bottom: 10px">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ldap_url"
|
||||
ng-model="$ctrl.settings.URLs[$index]"
|
||||
placeholder="e.g. 10.0.0.10:389 or myldap.domain.tld:389"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
<button
|
||||
ng-if="$index > 0"
|
||||
class="btn btn-sm btn-danger"
|
||||
type="button"
|
||||
ng-click="$ctrl.removeLDAPUrl($index)"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" feather="true" size="'md'"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Anonymous mode-->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label for="anonymous_mode" class="control-label text-left col-sm-3 col-lg-2">
|
||||
Anonymous mode
|
||||
<portainer-tooltip message="'Enable this option if the server is configured for Anonymous access.'"></portainer-tooltip>
|
||||
</label>
|
||||
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="anonymous_mode" ng-model="$ctrl.settings.AnonymousMode" limited-feature-dir="{{::$ctrl.limitedFeatureId}}" limited-feature-tabindex="-1" />
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !Anonymous mode-->
|
||||
|
||||
<div ng-if="!$ctrl.settings.AnonymousMode">
|
||||
<div class="form-group">
|
||||
<label for="ldap_username" class="col-sm-3 col-lg-2 control-label text-left">
|
||||
Reader DN
|
||||
<portainer-tooltip message="'Account that will be used to search for users.'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ldap_username"
|
||||
ng-model="$ctrl.settings.ReaderDN"
|
||||
placeholder="cn=user,dc=domain,dc=tld"
|
||||
ng-change="$ctrl.onAccountChange($ctrl.settings.ReaderDN)"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ldap_password" class="col-sm-3 col-lg-2 control-label text-left">
|
||||
Password
|
||||
<portainer-tooltip message="'If you do not enter a password, Portainer will leave the current password unchanged.'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
type="password"
|
||||
class="form-control"
|
||||
id="ldap_password"
|
||||
ng-model="$ctrl.settings.Password"
|
||||
placeholder="password"
|
||||
autocomplete="new-password"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.settings.AnonymousMode">
|
||||
<label for="ldap_domain_root" class="col-sm-3 col-lg-2 control-label text-left"> Domain root </label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ldap_domain_root"
|
||||
ng-model="$ctrl.domainSuffix"
|
||||
placeholder="dc=domain,dc=tld"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ldap-connectivity-check
|
||||
ng-if="!$ctrl.settings.TLSConfig.TLS && !$ctrl.settings.StartTLS"
|
||||
settings="$ctrl.settings"
|
||||
state="$ctrl.state"
|
||||
connectivity-check="$ctrl.connectivityCheck"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-connectivity-check>
|
||||
|
||||
<ldap-settings-security
|
||||
title="Connectivity Security"
|
||||
settings="$ctrl.settings"
|
||||
tlsca-cert="$ctrl.tlscaCert"
|
||||
upload-in-progress="$ctrl.state.uploadInProgress"
|
||||
on-tlsca-cert-change="($ctrl.onTlscaCertChange)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-settings-security>
|
||||
|
||||
<ldap-connectivity-check
|
||||
ng-if="$ctrl.settings.TLSConfig.TLS || $ctrl.settings.StartTLS"
|
||||
settings="$ctrl.settings"
|
||||
state="$ctrl.state"
|
||||
connectivity-check="$ctrl.connectivityCheck"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-connectivity-check>
|
||||
|
||||
<ldap-user-search
|
||||
style="margin-top: 5px"
|
||||
settings="$ctrl.settings.SearchSettings"
|
||||
domain-suffix="{{ $ctrl.domainSuffix }}"
|
||||
base-filter="(objectClass=inetOrgPerson)"
|
||||
on-search-click="($ctrl.onSearchUsersClick)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-user-search>
|
||||
|
||||
<ldap-group-search
|
||||
style="margin-top: 5px"
|
||||
settings="$ctrl.settings.GroupSearchSettings"
|
||||
domain-suffix="{{ $ctrl.domainSuffix }}"
|
||||
base-filter="(objectClass=groupOfNames)"
|
||||
on-search-click="($ctrl.onSearchGroupsClick)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-group-search>
|
||||
|
||||
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId"></ldap-settings-test-login>
|
||||
<save-auth-settings-button
|
||||
on-save-settings="($ctrl.onSaveSettings)"
|
||||
save-button-state="($ctrl.saveButtonState)"
|
||||
save-button-disabled="!$ctrl.saveButtonDisabled()"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></save-auth-settings-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.settings.AnonymousMode">
|
||||
<label for="ldap_domain_root" class="col-sm-3 col-lg-2 control-label text-left"> Domain root </label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="ldap_domain_root"
|
||||
ng-model="$ctrl.domainSuffix"
|
||||
placeholder="dc=domain,dc=tld"
|
||||
limited-feature-dir="{{::$ctrl.limitedFeatureId}}"
|
||||
limited-feature-tabindex="-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ldap-connectivity-check
|
||||
ng-if="!$ctrl.settings.TLSConfig.TLS && !$ctrl.settings.StartTLS"
|
||||
settings="$ctrl.settings"
|
||||
state="$ctrl.state"
|
||||
connectivity-check="$ctrl.connectivityCheck"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-connectivity-check>
|
||||
|
||||
<ldap-settings-security
|
||||
title="Connectivity Security"
|
||||
settings="$ctrl.settings"
|
||||
tlsca-cert="$ctrl.tlscaCert"
|
||||
upload-in-progress="$ctrl.state.uploadInProgress"
|
||||
on-tlsca-cert-change="($ctrl.onTlscaCertChange)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-settings-security>
|
||||
|
||||
<ldap-connectivity-check
|
||||
ng-if="$ctrl.settings.TLSConfig.TLS || $ctrl.settings.StartTLS"
|
||||
settings="$ctrl.settings"
|
||||
state="$ctrl.state"
|
||||
connectivity-check="$ctrl.connectivityCheck"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-connectivity-check>
|
||||
|
||||
<ldap-user-search
|
||||
style="margin-top: 5px"
|
||||
settings="$ctrl.settings.SearchSettings"
|
||||
domain-suffix="{{ $ctrl.domainSuffix }}"
|
||||
base-filter="(objectClass=inetOrgPerson)"
|
||||
on-search-click="($ctrl.onSearchUsersClick)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-user-search>
|
||||
|
||||
<ldap-group-search
|
||||
style="margin-top: 5px"
|
||||
settings="$ctrl.settings.GroupSearchSettings"
|
||||
domain-suffix="{{ $ctrl.domainSuffix }}"
|
||||
base-filter="(objectClass=groupOfNames)"
|
||||
on-search-click="($ctrl.onSearchGroupsClick)"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></ldap-group-search>
|
||||
|
||||
<ldap-settings-test-login settings="$ctrl.settings" limited-feature-id="$ctrl.limitedFeatureId"></ldap-settings-test-login>
|
||||
<save-auth-settings-button
|
||||
on-save-settings="($ctrl.onSaveSettings)"
|
||||
save-button-state="($ctrl.saveButtonState)"
|
||||
save-button-disabled="!$ctrl.saveButtonDisabled()"
|
||||
limited-feature-id="$ctrl.limitedFeatureId"
|
||||
></save-auth-settings-button>
|
||||
</ng-form>
|
||||
|
|
|
@ -1,46 +1,61 @@
|
|||
<page-header title="'User Activity'" breadcrumbs="['Activity Logs']" reload="true"> </page-header>
|
||||
|
||||
<div class="be-indicator-container">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<div class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="dateRangeInput" class="col-sm-2 control-label text-left">Date Range</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" disabled />
|
||||
<div class="be-indicator-container limited-be">
|
||||
<div class="overlay">
|
||||
<div class="limited-be-link vertical-center"
|
||||
><be-feature-indicator feature="$ctrl.limitedFeature"></be-feature-indicator
|
||||
><portainer-tooltip message="'This feature is currently limited to Business Edition users only. '"></portainer-tooltip
|
||||
></div>
|
||||
<div class="limited-be-content">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<div class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="dateRangeInput" class="col-sm-2 control-label text-left">Date Range</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" disabled />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" class-name="'icon icon-sm icon-primary'"></pr-icon>
|
||||
Portainer user activity logs have a maximum retention of 7 days.
|
||||
</p>
|
||||
<div>
|
||||
<button type="button" class="btn btn-sm btn-primary" limited-feature-dir="{{::$ctrl.limitedFeature}}" limited-feature-class="limited-be" limited-feature-disabled>
|
||||
<pr-icon icon="'download'" feather="true" icon-class="'icon icon-sm'"></pr-icon>
|
||||
Export as CSV
|
||||
</button>
|
||||
<be-feature-indicator feature="$ctrl.limitedFeature"></be-feature-indicator>
|
||||
</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
||||
|
||||
<div class="be-indicator-container">
|
||||
<div class="row">
|
||||
<activity-logs-datatable
|
||||
logs="$ctrl.state.logs"
|
||||
keyword="$ctrl.state.keyword"
|
||||
sort="$ctrl.state.sort"
|
||||
limit="$ctrl.state.limit"
|
||||
context-filter="$ctrl.state.contextFilter"
|
||||
total-items="$ctrl.state.totalItems"
|
||||
current-page="$ctrl.state.currentPage"
|
||||
feature="{{:: $ctrl.limitedFeature}}"
|
||||
on-change-keyword="($ctrl.onChangeKeyword)"
|
||||
on-change-sort="($ctrl.onChangeSort)"
|
||||
on-change-limit="($ctrl.onChangeLimit)"
|
||||
on-change-page="($ctrl.onChangePage)"
|
||||
></activity-logs-datatable>
|
||||
<p class="text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" class-name="'icon icon-sm icon-primary'"></pr-icon>
|
||||
Portainer user activity logs have a maximum retention of 7 days.
|
||||
</p>
|
||||
<div>
|
||||
<button type="button" class="btn btn-sm btn-primary" limited-feature-dir="{{::$ctrl.limitedFeature}}" limited-feature-class="limited-be" limited-feature-disabled>
|
||||
<pr-icon icon="'download'" feather="true" icon-class="'icon icon-sm'"></pr-icon>
|
||||
Export as CSV
|
||||
</button>
|
||||
</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="be-indicator-container limited-be">
|
||||
<div class="overlay">
|
||||
<div class="limited-be-link vertical-center"
|
||||
><be-feature-indicator feature="$ctrl.limitedFeature"></be-feature-indicator
|
||||
><portainer-tooltip message="'This feature is currently limited to Business Edition users only. '"></portainer-tooltip
|
||||
></div>
|
||||
<div class="limited-be-content">
|
||||
<div class="row">
|
||||
<activity-logs-datatable
|
||||
logs="$ctrl.state.logs"
|
||||
keyword="$ctrl.state.keyword"
|
||||
sort="$ctrl.state.sort"
|
||||
limit="$ctrl.state.limit"
|
||||
context-filter="$ctrl.state.contextFilter"
|
||||
total-items="$ctrl.state.totalItems"
|
||||
current-page="$ctrl.state.currentPage"
|
||||
feature="{{:: $ctrl.limitedFeature}}"
|
||||
on-change-keyword="($ctrl.onChangeKeyword)"
|
||||
on-change-sort="($ctrl.onChangeSort)"
|
||||
on-change-limit="($ctrl.onChangeLimit)"
|
||||
on-change-page="($ctrl.onChangePage)"
|
||||
></activity-logs-datatable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<be-feature-indicator feature="{{::$ctrl.feature}}"></be-feature-indicator>
|
||||
</div>
|
||||
<div class="vertical-center">
|
||||
<datatable-searchbar on-change="($ctrl.onChangeKeyword)" value="$ctrl.keyword"></datatable-searchbar>
|
||||
<datatable-searchbar on-change="($ctrl.onChangeKeyword)"></datatable-searchbar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
|
|
|
@ -1,48 +1,63 @@
|
|||
<page-header title="'User Activity'" breadcrumbs="['User authentication activity']" reload="true"> </page-header>
|
||||
|
||||
<div class="be-indicator-container">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<div class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="dateRangeInput" class="col-sm-2 control-label text-left">Date Range</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" disabled />
|
||||
<div class="be-indicator-container limited-be">
|
||||
<div class="overlay">
|
||||
<div class="limited-be-link vertical-center"
|
||||
><be-feature-indicator feature="$ctrl.limitedFeature"></be-feature-indicator
|
||||
><portainer-tooltip message="'This feature is currently limited to Business Edition users only. '"></portainer-tooltip
|
||||
></div>
|
||||
<div class="limited-be-content">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<div class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="dateRangeInput" class="col-sm-2 control-label text-left">Date Range</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" disabled />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" class-name="'icon icon-sm icon-primary'"></pr-icon>
|
||||
Portainer user authentication activity logs have a maximum retention of 7 days.
|
||||
</p>
|
||||
<div>
|
||||
<button type="button" class="btn btn-sm btn-primary" limited-feature-dir="{{::$ctrl.limitedFeature}}" limited-feature-class="limited-be" limited-feature-disabled
|
||||
><pr-icon icon="'download'" feather="true" icon-class="'icon icon-sm'"></pr-icon>Export as CSV
|
||||
</button>
|
||||
<be-feature-indicator feature="$ctrl.limitedFeature"></be-feature-indicator>
|
||||
</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
||||
|
||||
<div class="be-indicator-container">
|
||||
<div class="row">
|
||||
<auth-logs-datatable
|
||||
logs="$ctrl.state.logs"
|
||||
keyword="$ctrl.state.keyword"
|
||||
sort="$ctrl.state.sort"
|
||||
limit="$ctrl.state.limit"
|
||||
context-filter="$ctrl.state.contextFilter"
|
||||
type-filter="$ctrl.state.typeFilter"
|
||||
total-items="$ctrl.state.totalItems"
|
||||
current-page="$ctrl.state.currentPage"
|
||||
feature="{{:: $ctrl.limitedFeature}}"
|
||||
on-change-context-filter="($ctrl.onChangeContextFilter)"
|
||||
on-change-type-filter="($ctrl.onChangeTypeFilter)"
|
||||
on-change-keyword="($ctrl.onChangeKeyword)"
|
||||
on-change-sort="($ctrl.onChangeSort)"
|
||||
on-change-limit="($ctrl.onChangeLimit)"
|
||||
on-change-page="($ctrl.onChangePage)"
|
||||
></auth-logs-datatable>
|
||||
<p class="text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" class-name="'icon icon-sm icon-primary'"></pr-icon>
|
||||
Portainer user authentication activity logs have a maximum retention of 7 days.
|
||||
</p>
|
||||
<div>
|
||||
<button type="button" class="btn btn-sm btn-primary" limited-feature-dir="{{::$ctrl.limitedFeature}}" limited-feature-class="limited-be" limited-feature-disabled
|
||||
><pr-icon icon="'download'" feather="true" icon-class="'icon icon-sm'"></pr-icon>Export as CSV
|
||||
</button>
|
||||
</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="be-indicator-container limited-be">
|
||||
<div class="overlay">
|
||||
<div class="limited-be-link vertical-center"
|
||||
><be-feature-indicator feature="$ctrl.limitedFeature"></be-feature-indicator
|
||||
><portainer-tooltip message="'This feature is currently limited to Business Edition users only. '"></portainer-tooltip
|
||||
></div>
|
||||
<div class="limited-be-content">
|
||||
<div class="row">
|
||||
<auth-logs-datatable
|
||||
logs="$ctrl.state.logs"
|
||||
keyword="$ctrl.state.keyword"
|
||||
sort="$ctrl.state.sort"
|
||||
limit="$ctrl.state.limit"
|
||||
context-filter="$ctrl.state.contextFilter"
|
||||
type-filter="$ctrl.state.typeFilter"
|
||||
total-items="$ctrl.state.totalItems"
|
||||
current-page="$ctrl.state.currentPage"
|
||||
feature="{{:: $ctrl.limitedFeature}}"
|
||||
on-change-context-filter="($ctrl.onChangeContextFilter)"
|
||||
on-change-type-filter="($ctrl.onChangeTypeFilter)"
|
||||
on-change-keyword="($ctrl.onChangeKeyword)"
|
||||
on-change-sort="($ctrl.onChangeSort)"
|
||||
on-change-limit="($ctrl.onChangeLimit)"
|
||||
on-change-page="($ctrl.onChangePage)"
|
||||
></auth-logs-datatable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { PropsWithChildren } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { Briefcase } from 'react-feather';
|
||||
|
||||
import './BEFeatureIndicator.css';
|
||||
|
||||
|
@ -24,19 +25,16 @@ export function BEFeatureIndicator({
|
|||
if (!limitedToBE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
className={clsx('be-indicator', className)}
|
||||
className={clsx('be-indicator vertical-center', className)}
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{children}
|
||||
{showIcon && (
|
||||
<i className="fas fa-briefcase space-right be-indicator-icon" />
|
||||
)}
|
||||
<span className="be-indicator-label break-words">
|
||||
{showIcon && <Briefcase className="icon icon-sm vertical-center" />}
|
||||
<span className="be-indicator-label break-words space-left">
|
||||
Business Edition Feature
|
||||
</span>
|
||||
</a>
|
||||
|
|
Loading…
Reference in New Issue