Minor fixes

This commit is contained in:
dnknth 2023-01-20 16:26:17 +01:00 committed by Daniel Knauth
parent 9bf81e6c62
commit 067c56a554
16 changed files with 103 additions and 89 deletions

View File

@ -2,8 +2,6 @@
.git
.venv3
dist
docker-demo
env-example
env.*
etc
node_modules
screenshot.png

View File

@ -16,10 +16,14 @@ run: app.py settings.py .env .venv3 dist
.venv3/bin/pip3 install -r $<
touch $@
dist: package.json
npm install
dist: node_modules
npm run build
node_modules: package.json
npm install
npm audit
touch $@
clean:
rm -rf dist __pycache__

View File

@ -5,7 +5,6 @@ services:
image: dnknth/ldap-demo
ports:
- 127.0.0.1:389:389
env_file: env.demo
restart: unless-stopped
healthcheck:
test: "ldapsearch -x -b dc=flintstones,dc=com cn > /dev/null"
@ -22,8 +21,8 @@ services:
environment:
LDAP_URL: "ldap://ldap/"
BASE_DN: "dc=flintstones,dc=com"
BIND_DN: "cn=Fred Flintstone,ou=People,dc=flintstones,dc=com"
BIND_PASSWORD: yabbadabbado
BIND_DN: "${BIND_DN:-cn=Fred Flintstone,ou=People,dc=flintstones,dc=com}"
BIND_PASSWORD: "${BIND_PASSWORD:-yabbadabbado}"
restart: unless-stopped
healthcheck:
test: "wget -q -O /dev/null http://localhost:5000"

BIN
package-lock.json generated

Binary file not shown.

View File

@ -14,14 +14,14 @@
"vue": "^2.7.0"
},
"devDependencies": {
"vite": "^4.0.0",
"@vitejs/plugin-vue2": "^2.0.0",
"eslint": "latest"
"eslint": "latest",
"vite": "^4.0.0",
"vite-plugin-compression": "^0.5.1"
},
"eslintConfig": {
"extends": [
"eslint:recommended"
],
"root": true,
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2015

View File

@ -18,7 +18,7 @@
<b-col id="main">
<b-alert dismissible fade :variant="error.type"
:show="error &amp;&amp; error.counter" @dismissed="error.counter=0">
:show="error && error.counter" @dismissed="error.counter=0">
{{ error.msg }}
</b-alert>
@ -34,14 +34,14 @@
<script>
import AttributeCard from './components/schema/AttributeCard.vue'
import Editor from './components/editor/Editor.vue'
import { LdapSchema } from './components/schema/schema.js'
import LdifImportDialog from './components/LdifImportDialog.vue'
import NavBar from './components/NavBar.vue'
import ObjectClassCard from './components/schema/ObjectClassCard.vue'
import { request } from './request.js'
import TreeView from './components/TreeView.vue'
import AttributeCard from './components/schema/AttributeCard.vue';
import Editor from './components/editor/Editor.vue';
import { LdapSchema } from './components/schema/schema.js';
import LdifImportDialog from './components/LdifImportDialog.vue';
import NavBar from './components/NavBar.vue';
import ObjectClassCard from './components/schema/ObjectClassCard.vue';
import { request } from './request.js';
import TreeView from './components/TreeView.vue';
export default {

View File

@ -35,7 +35,7 @@
<script>
import NodeLabel from './NodeLabel.vue'
import NodeLabel from './NodeLabel.vue';
import SearchResults from './SearchResults.vue';
export default {

View File

@ -1,6 +1,6 @@
<template>
<div id="tree-view">
<ul id="tree" v-if="shown &amp;&amp; tree" class="list-unstyled">
<ul id="tree" v-if="shown && tree" class="list-unstyled">
<li v-for="item in tree.visible()" :key="item.dn"
:id="item.dn" :class="item.structuralObjectClass">
<span v-for="i in (item.level - tree.level)" class="indent" :key="i"></span>
@ -22,7 +22,7 @@
<script>
import NodeLabel from './NodeLabel.vue'
import NodeLabel from './NodeLabel.vue';
function Node(json) {

View File

@ -4,7 +4,7 @@
<p class="strong">This action is irreversible.</p>
<div v-if="subtree &amp;&amp; subtree.length">
<div v-if="subtree && subtree.length">
<p class="red">The following child nodes will be also deleted:</p>
<div v-for="node in subtree" :key="node.dn">
<span v-for="i in node.level" class="indent" :key="i"></span>
@ -22,7 +22,7 @@
<script>
import NodeLabel from '../NodeLabel.vue'
import NodeLabel from '../NodeLabel.vue';
export default {

View File

@ -4,7 +4,7 @@
@submit.prevent="save" @reset="load(entry.meta.dn);" @focusin="onFocus">
<new-entry-dialog :entry="entry" :schema="schema"
@replace-entry="entry = $event;"
@replace-entry="newEntry"
@select-dn="$emit('select-dn')" />
<copy-entry-dialog :entry="entry"
@select-dn="$emit('select-dn', $event)" />
@ -23,24 +23,26 @@
<add-object-class-dialog :entry="entry" @update-form="prepareForm" />
<b-card id="editor">
<div slot="header">
<b-nav>
<b-nav-item v-if="entry.meta.isNew">
<node-label :dn="entry.meta.dn" :oc="structural" />
</b-nav-item>
<b-nav-item-dropdown v-else extra-toggle-classes="nav-link-custom" right class="entry-menu">
<template #button-content>
<div>
<slot name="header">
<b-nav>
<b-nav-item v-if="entry.meta.isNew">
<node-label :dn="entry.meta.dn" :oc="structural" />
</template>
<b-dropdown-item v-b-modal.new-entry>Add child</b-dropdown-item>
<b-dropdown-item v-b-modal.copy-entry>Copy…</b-dropdown-item>
<b-dropdown-item v-b-modal.rename-entry>Rename…</b-dropdown-item>
<b-dropdown-item @click="ldif">Export</b-dropdown-item>
<b-dropdown-item v-b-modal.confirm><span class="red">Delete</span></b-dropdown-item>
</b-nav-item-dropdown>
</b-nav>
<span v-if="entry.meta.isNew" class="close-box control" v-b-modal.confirm-discard>⊗</span>
<span v-else class="close-box control" @click="$emit('select-dn')"></span>
</b-nav-item>
<b-nav-item-dropdown v-else extra-toggle-classes="nav-link-custom" right class="entry-menu">
<template #button-content>
<node-label :dn="entry.meta.dn" :oc="structural" />
</template>
<b-dropdown-item v-b-modal.new-entry>Add child</b-dropdown-item>
<b-dropdown-item v-b-modal.copy-entry>Copy…</b-dropdown-item>
<b-dropdown-item v-b-modal.rename-entry>Rename…</b-dropdown-item>
<b-dropdown-item @click="ldif">Export</b-dropdown-item>
<b-dropdown-item v-b-modal.confirm><span class="red">Delete</span></b-dropdown-item>
</b-nav-item-dropdown>
</b-nav>
<span v-if="entry.meta.isNew" class="close-box control" v-b-modal.confirm-discard>⊗</span>
<span v-else class="close-box control" @click="$emit('select-dn')"></span>
</slot>
</div>
<table id="entry">
@ -70,18 +72,18 @@
<script>
import AddAttributeDialog from './AddAttributeDialog.vue'
import AddObjectClassDialog from './AddObjectClassDialog.vue'
import AddPhotoDialog from './AddPhotoDialog.vue'
import CopyEntryDialog from './CopyEntryDialog.vue'
import DeleteEntryDialog from './DeleteEntryDialog.vue'
import DiscardEntryDialog from './DiscardEntryDialog.vue'
import FormRow from './FormRow.vue'
import NewEntryDialog from './NewEntryDialog.vue'
import NodeLabel from '../NodeLabel.vue'
import PasswordChangeDialog from './PasswordChangeDialog.vue'
import RenameEntryDialog from './RenameEntryDialog.vue'
import { request } from '../../request.js'
import AddAttributeDialog from './AddAttributeDialog.vue';
import AddObjectClassDialog from './AddObjectClassDialog.vue';
import AddPhotoDialog from './AddPhotoDialog.vue';
import CopyEntryDialog from './CopyEntryDialog.vue';
import DeleteEntryDialog from './DeleteEntryDialog.vue';
import DiscardEntryDialog from './DiscardEntryDialog.vue';
import FormRow from './FormRow.vue';
import NewEntryDialog from './NewEntryDialog.vue';
import NodeLabel from '../NodeLabel.vue';
import PasswordChangeDialog from './PasswordChangeDialog.vue';
import RenameEntryDialog from './RenameEntryDialog.vue';
import { request } from '../../request.js';
function unique(element, index, array) {
@ -158,6 +160,11 @@ export default {
if (el.tagName == 'INPUT' && el.id) this.focused = el.id;
},
newEntry: function(entry) {
this.entry = entry;
this.prepareForm();
},
prepareForm: function(focused) {
this.must.filter(attr => !this.entry.attrs[attr])
.forEach(attr => this.$set(this.entry.attrs, attr, ['']));

View File

@ -15,7 +15,7 @@
placeholder="New password" type="password" />
<input v-model="repeated" class="mb-3 form-control"
:class="{ red: repeated &amp;&amp; !passwordsMatch }"
:class="{ red: repeated && !passwordsMatch }"
placeholder="Repeat new password" type="password" @keyup.enter="done" />
</b-modal>
</template>

View File

@ -1,13 +1,13 @@
<template>
<b-card v-if="attr" :title="attr.desc" title-tag="strong">
<template slot="header">
<span class="header">{{ attr.names.join(', ') }}</span>
<b-card v-if="attr" :title="attr.names.join(', ')" title-tag="strong">
<slot name="header">
<div class="header">{{ attr.desc }}</div>
<span class="control close-box" @click="$emit('display-attr')"></span>
</template>
</slot>
<ul>
<template v-for="(val, key) in attr">
<li :key="key" v-if="val &amp;&amp; hiddenFields.indexOf(key) == -1">
<li :key="key" v-if="val && hiddenFields.indexOf(key) == -1">
{{ key }}: {{ val }}
</li>
</template>
@ -26,7 +26,7 @@
<script>
import { LdapSchema } from './schema.js'
import { LdapSchema } from './schema.js';
export default {
@ -51,7 +51,7 @@ export default {
</script>
<style scoped>
span.header {
font-weight: bold;
div.header {
margin-bottom: 1ex;
}
</style>

View File

@ -1,10 +1,10 @@
<template>
<b-card v-if="oc" :title="oc.desc" title-tag="strong" class="oc-card">
<template slot="header">
<span class="header">{{ oc.name }}</span>
<b-card v-if="oc" :title="oc.name" title-tag="strong" class="oc-card">
<slot name="header">
<div class="header">{{ oc.desc }}</div>
<span class="control close-box" @click="$emit('display-oc', undefined)"></span>
</template>
</slot>
<div v-if="oc.must.length"> Required attributes:
<ul>
<li v-for="name in oc.must" :key="name">
@ -33,7 +33,7 @@
<script>
import { LdapSchema } from './schema.js'
import { LdapSchema } from './schema.js';
export default {
@ -49,7 +49,7 @@ export default {
</script>
<style scoped>
span.header {
font-weight: bold;
div.header {
margin-bottom: 1ex;
}
</style>

View File

@ -1,19 +1,17 @@
import 'core-js/stable'
import 'regenerator-runtime/runtime'
import 'intersection-observer'
"use strict";
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import 'font-awesome/css/font-awesome.min.css'
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';
import 'font-awesome/css/font-awesome.min.css';
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue)
import Vue from 'vue';
import BootstrapVue from 'bootstrap-vue';
import App from './App.vue'
import App from './App.vue';
Vue.config.productionTip = false
Vue.use(BootstrapVue);
Vue.config.productionTip = false;
new Vue({
render: h => h(App),
}).$mount('#app')
}).$mount('#app');

View File

@ -12,8 +12,8 @@
* }
*/
export function request(opts) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
return new Promise(function(resolve, reject) { // eslint-disable-line no-undef
var xhr = new XMLHttpRequest(); // eslint-disable-line no-undef
xhr.open(opts.method || 'GET', opts.url);
if (opts.responseType) xhr.responseType = opts.responseType;
xhr.onload = function () {

View File

@ -1,10 +1,14 @@
import { defineConfig } from 'vite';
import viteCompression from 'vite-plugin-compression';
import vue from '@vitejs/plugin-vue2';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
plugins: [
vue(),
viteCompression()
],
base: './',
@ -16,6 +20,10 @@ export default defineConfig({
}
},
build: {
chunkSizeWarningLimit: 600
},
css: { // https://github.com/vitejs/vite/issues/6333#issuecomment-1003318603
postcss: {
plugins: [