navigation in backoffice works again
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
<template>
|
||||
<div class="app" :class="getClassList()">
|
||||
<template v-if="isAuthenticated">
|
||||
<!--<app-navigation />-->
|
||||
<app-navigation />
|
||||
<div class="app-main">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<!--<app-overlays />
|
||||
<app-notifications />-->
|
||||
<app-overlays />
|
||||
<!--<app-notifications />-->
|
||||
</template>
|
||||
<!--<app-login v-else />-->
|
||||
<app-login v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import '../Sass/app.scss'
|
||||
//import AppNavigation from 'zero/navigation.vue'
|
||||
//import AppLogin from 'zero/pages/login/login.vue'
|
||||
//import AppOverlays from 'zero/components/overlays/overlay-holder.vue'
|
||||
import AppNavigation from 'zero/navigation.vue'
|
||||
import AppLogin from 'zero/pages/login/login.vue'
|
||||
import AppOverlays from 'zero/components/overlays/overlay-holder.vue'
|
||||
//import AppNotifications from 'zero/components/notifications/notification-holder.vue'
|
||||
import AuthApi from 'zero/services/auth.js';
|
||||
import EventHub from 'zero/services/eventhub';
|
||||
@@ -28,7 +28,7 @@
|
||||
export default {
|
||||
name: 'app',
|
||||
|
||||
//components: { AppNavigation, AppOverlays, AppLogin, AppNotifications },
|
||||
components: { AppNavigation, AppOverlays, AppLogin },
|
||||
|
||||
data: () => ({
|
||||
isAuthenticated: false
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['click'],
|
||||
|
||||
computed: {
|
||||
application()
|
||||
{
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
export default {
|
||||
name: 'uiButton',
|
||||
|
||||
emits: ['click'],
|
||||
|
||||
props: {
|
||||
label: {
|
||||
type: String
|
||||
@@ -130,17 +132,6 @@
|
||||
{
|
||||
this.stateTimeout = setTimeout(() =>
|
||||
{
|
||||
//const stateUpdate = 'update:state';
|
||||
|
||||
//// check if :state property has .sync modifier
|
||||
//let listeners = this.$options._parentListeners;
|
||||
//const hasSyncModifier = listeners && listeners[stateUpdate];
|
||||
|
||||
//if (!hasSyncModifier)
|
||||
//{
|
||||
// console.warn(`ui-button: Add the .sync modifier to the "state" property, as changing the state to "${STATE_SUCCESS}" or "${STATE_ERROR}" will automatically set it back to "${STATE_DEFAULT}" after the state duration timeout`);
|
||||
//}
|
||||
|
||||
this.stateDisplay = STATE_DEFAULT;
|
||||
}, this.stateDuration);
|
||||
}
|
||||
@@ -148,7 +139,6 @@
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
tryClick(ev)
|
||||
{
|
||||
if (this.isDefaultState)
|
||||
@@ -156,7 +146,6 @@
|
||||
this.$emit('click', ev);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<button type="button" class="ui-dot-button" :disabled="disabled" @click="tryClick" :title="title | localize">
|
||||
<button type="button" class="ui-dot-button" :disabled="disabled" @click="tryClick" v-localize:title="title">
|
||||
<span class="sr-only" v-localize="title"></span>
|
||||
<i class="ui-button-icon fth-more-horizontal"></i>
|
||||
</button>
|
||||
@@ -10,6 +10,8 @@
|
||||
export default {
|
||||
name: 'uiDotButton',
|
||||
|
||||
emits: ['click'],
|
||||
|
||||
props: {
|
||||
state: {
|
||||
type: String,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<button type="button" class="ui-icon-button" :disabled="disabled" :class="'type-' + type.split(' ').join(' type-')" @click="tryClick" :title="title | localize">
|
||||
<button type="button" class="ui-icon-button" :disabled="disabled" :class="'type-' + type.split(' ').join(' type-')" @click="tryClick" v-localize:title="title">
|
||||
<span class="sr-only" v-localize="title"></span>
|
||||
<i class="ui-button-icon" :class="icon"></i>
|
||||
</button>
|
||||
@@ -10,6 +10,8 @@
|
||||
export default {
|
||||
name: 'uiIconButton',
|
||||
|
||||
emits: ['click'],
|
||||
|
||||
props: {
|
||||
state: {
|
||||
type: String,
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
export default {
|
||||
name: 'uiSelectButton',
|
||||
|
||||
emits: ['click'],
|
||||
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
methods: {
|
||||
|
||||
select(value)
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['count', 'select'],
|
||||
|
||||
components: { UiPagination },
|
||||
|
||||
watch: {
|
||||
@@ -116,7 +118,7 @@
|
||||
computed: {
|
||||
actionsDefined()
|
||||
{
|
||||
return this.$scopedSlots.hasOwnProperty('actions');
|
||||
return typeof this.$slots.actions === 'function';
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
export default {
|
||||
name: 'uiAlias',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
export default {
|
||||
name: 'uiCheckList',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<template>
|
||||
<!-- // TODO notfound view works and can be used here -->
|
||||
<div class="page page-error" :class="{'theme-dark': dark }">
|
||||
<i class="page-error-icon fth-cloud-snow"></i>
|
||||
<p class="page-error-text">
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
export default {
|
||||
name: 'uiFormHeader',
|
||||
|
||||
emits: ['delete'],
|
||||
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
@@ -69,7 +71,7 @@
|
||||
computed: {
|
||||
actionsDefined()
|
||||
{
|
||||
return !this.isCreate && (this.canDelete || this.$scopedSlots.hasOwnProperty('actions'));
|
||||
return !this.isCreate && (this.canDelete || typeof this.$slots.actions === 'function');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['load', 'submit'],
|
||||
|
||||
data: () => ({
|
||||
dirty: false,
|
||||
loadingState: 'default',
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
export default {
|
||||
name: 'uiInputList',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
addLabel: {
|
||||
type: String,
|
||||
|
||||
@@ -66,6 +66,8 @@
|
||||
export default {
|
||||
name: 'uiMediaOld',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
export default {
|
||||
name: 'uiRte',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['input', 'change', 'submit'],
|
||||
|
||||
computed: {
|
||||
|
||||
},
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
export default {
|
||||
name: 'uiTags',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
addLabel: {
|
||||
type: String,
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
export default {
|
||||
name: 'uiToggle',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
export default {
|
||||
name: 'uiModulePreview',
|
||||
|
||||
emits: ['edit', 'remove', 'isActive'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
export default {
|
||||
name: 'uiModulesSelect',
|
||||
|
||||
emits: ['selected'],
|
||||
|
||||
props: {
|
||||
value: Array,
|
||||
config: Object,
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
export default {
|
||||
name: 'uiModules',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
|
||||
|
||||
<script>
|
||||
import Overlay from 'zero/services/overlay.js'
|
||||
|
||||
export default {
|
||||
|
||||
props: {
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
<template>
|
||||
<!-- // TODO remove surrounding div as soon as we can have multiple roots (vue 3) -->
|
||||
<div @click="onClickShim">
|
||||
<button v-if="!confirming" :disabled="disabled" type="button" @click="onClick" class="ui-dropdown-button" :class="{ 'has-icon': icon, 'is-active': selected, 'is-multiline': multiline }">
|
||||
<i v-if="icon" class="ui-dropdown-button-icon" :class="icon"></i>
|
||||
{{label | localize}}
|
||||
<i v-if="selected" class="ui-dropdown-button-selected fth-check"></i>
|
||||
<i v-if="loading" class="ui-dropdown-button-progress"></i>
|
||||
</button>
|
||||
<div v-if="confirming" class="ui-dropdown-button-confirmation">
|
||||
<i v-if="icon" class="ui-dropdown-button-icon" :class="icon"></i>
|
||||
{{label | localize}}
|
||||
<ui-button type="small primary" label="OK" @click="onClick($event, true)" />
|
||||
<ui-button type="small light" label="Cancel" @click="confirming=false" />
|
||||
</div>
|
||||
<button v-if="!confirming" :disabled="disabled" type="button" @click="onClick" class="ui-dropdown-button" :class="{ 'has-icon': icon, 'is-active': selected, 'is-multiline': multiline }">
|
||||
<i v-if="icon" class="ui-dropdown-button-icon" :class="icon"></i>
|
||||
<span v-localize="label"></span>
|
||||
<i v-if="selected" class="ui-dropdown-button-selected fth-check"></i>
|
||||
<i v-if="loading" class="ui-dropdown-button-progress"></i>
|
||||
</button>
|
||||
<div v-if="confirming" class="ui-dropdown-button-confirmation">
|
||||
<i v-if="icon" class="ui-dropdown-button-icon" :class="icon"></i>
|
||||
<span v-localize="label"></span>
|
||||
<ui-button type="small primary" label="OK" @click="onClick($event, true)" />
|
||||
<ui-button type="small light" label="Cancel" @click="confirming=false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -23,6 +20,8 @@
|
||||
export default {
|
||||
name: 'uiDropdownButton',
|
||||
|
||||
emits: ['click', 'hide'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
default: null
|
||||
@@ -126,14 +125,7 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onClickShim(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
export default {
|
||||
name: 'uiDropdown',
|
||||
|
||||
emits: ['opened', 'closed'],
|
||||
|
||||
props: {
|
||||
align: {
|
||||
type: String,
|
||||
@@ -39,7 +41,7 @@
|
||||
|
||||
hasButton()
|
||||
{
|
||||
return this.$scopedSlots.hasOwnProperty('button');
|
||||
return typeof this.$slots.button === 'function';
|
||||
},
|
||||
|
||||
dropdownClasses()
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
|
||||
|
||||
<script>
|
||||
import Overlay from 'zero/services/overlay.js'
|
||||
import EventHub from 'zero/services/eventhub';
|
||||
import { filter as _filter } from 'underscore';
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
instances: Overlay.instances
|
||||
instances: []
|
||||
}),
|
||||
|
||||
computed: {
|
||||
@@ -28,6 +28,19 @@
|
||||
}
|
||||
},
|
||||
|
||||
mounted()
|
||||
{
|
||||
EventHub.on('overlay:open', instances =>
|
||||
{
|
||||
console.info('open');
|
||||
this.instances = instances;
|
||||
});
|
||||
EventHub.on('overlay:close', instances =>
|
||||
{
|
||||
this.instances = instances;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
close(instance)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
export default {
|
||||
name: 'uiPagination',
|
||||
|
||||
emits: ['update:page', 'change'],
|
||||
|
||||
props: {
|
||||
pages: {
|
||||
type: Number,
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
export default {
|
||||
name: 'uiPermissions',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
export default {
|
||||
name: 'uiColorpicker',
|
||||
|
||||
emits: ['change', 'input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
export default {
|
||||
name: 'uiCountrypicker',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Array],
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
export default {
|
||||
name: 'uiDatepicker',
|
||||
|
||||
emits: ['change', 'input'],
|
||||
|
||||
components: { DatepickerOverlay },
|
||||
|
||||
props: {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['change'],
|
||||
|
||||
data: () => ({
|
||||
date: null,
|
||||
initialized: false
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
export default {
|
||||
name: 'uiDaterangepicker',
|
||||
|
||||
emits: ['change', 'input'],
|
||||
|
||||
components: { DaterangepickerOverlay },
|
||||
|
||||
props: {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
export default {
|
||||
name: 'uiIconpicker',
|
||||
|
||||
emits: ['change', 'input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
export default {
|
||||
name: 'uiMediapicker',
|
||||
|
||||
emits: ['change', 'input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [Array, String],
|
||||
|
||||
@@ -150,6 +150,8 @@
|
||||
export default {
|
||||
name: 'uiPick',
|
||||
|
||||
emits: ['change', 'input', 'select', 'deselect'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Array],
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
export default {
|
||||
name: 'uiUserpicker',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Array],
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// will be used very frequently. Components are registered using the
|
||||
// PascalCased version of their file name.
|
||||
|
||||
import Vue from 'vue';
|
||||
|
||||
let components = [];
|
||||
//const directories = ['buttons', 'forms', 'messages', 'tables', 'tabs'];
|
||||
|
||||
// TODO this file will import all vue component files with subdirectories
|
||||
@@ -42,6 +41,21 @@ requireComponent.keys().forEach((path) =>
|
||||
// Concatenated
|
||||
.join('');
|
||||
|
||||
// Globally register the component
|
||||
Vue.component(componentName, componentConfig.default || componentConfig);
|
||||
});
|
||||
if (componentName === 'uiOverlay')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
components.push({
|
||||
name: componentName,
|
||||
config: componentConfig.default || componentConfig
|
||||
})
|
||||
});
|
||||
|
||||
export default function (app)
|
||||
{
|
||||
components.forEach(component =>
|
||||
{
|
||||
app.component(component.name, component.config);
|
||||
});
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="ui-table-filter">
|
||||
<ui-search v-if="!hideSearch" v-model="value.search" class="onbg" />
|
||||
<ui-search v-if="!hideSearch" v-model="config.search" class="onbg" />
|
||||
<ui-dropdown v-if="!hideFilter && filters.length" align="right">
|
||||
<template v-slot:button>
|
||||
<ui-button v-if="!hideFilter" type="light onbg" :label="filterLabel" caret="down" />
|
||||
@@ -18,11 +18,11 @@
|
||||
</template>
|
||||
<slot name="actions"></slot>
|
||||
</ui-dropdown>
|
||||
<ui-dropdown v-if="value.actions && value.actions.length > 0" align="right">
|
||||
<ui-dropdown v-if="config.actions && config.actions.length > 0" align="right">
|
||||
<template v-slot:button>
|
||||
<ui-button type="light onbg" icon="fth-more-horizontal" />
|
||||
</template>
|
||||
<ui-dropdown-button v-for="(action, index) in value.actions" :key="index" :value="action" :prevent="action.autoclose === false" :label="action.label" :icon="action.icon" @click="onActionClicked" />
|
||||
<ui-dropdown-button v-for="(action, index) in config.actions" :key="index" :value="action" :prevent="action.autoclose === false" :label="action.label" :icon="action.icon" @click="onActionClicked" />
|
||||
</ui-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
@@ -37,8 +37,10 @@
|
||||
export default {
|
||||
name: 'uiTableFilter',
|
||||
|
||||
emits: ['filter'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
config: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () =>
|
||||
@@ -62,7 +64,7 @@
|
||||
},
|
||||
|
||||
watch: {
|
||||
value: function (value)
|
||||
config: function (value)
|
||||
{
|
||||
this.reload();
|
||||
}
|
||||
@@ -100,9 +102,9 @@
|
||||
|
||||
reload()
|
||||
{
|
||||
this.hideFilter = typeof this.value.filter !== 'object';
|
||||
this.hideSearch = typeof this.value.search === false;
|
||||
this.hideSelection = this.value.selectable !== true;
|
||||
this.hideFilter = typeof this.config.filter !== 'object';
|
||||
this.hideSearch = typeof this.config.search === false;
|
||||
this.hideSelection = this.config.selectable !== true;
|
||||
this.filters = JSON.parse(localStorage.getItem(this.storageKey) || "[]");
|
||||
},
|
||||
|
||||
@@ -125,7 +127,7 @@
|
||||
{
|
||||
let model = {
|
||||
name: null,
|
||||
filter: this.value.filter.model
|
||||
filter: this.config.filter.model
|
||||
};
|
||||
|
||||
if (id)
|
||||
@@ -137,9 +139,9 @@
|
||||
component: FilterOverlay,
|
||||
display: 'editor',
|
||||
title: 'Filter',
|
||||
defaults: this.value.filter.model,
|
||||
defaults: this.config.filter.model,
|
||||
model: model,
|
||||
fields: this.value.filter.fields,
|
||||
fields: this.config.filter.fields,
|
||||
canSave: !!this.alias,
|
||||
isCreate: !id
|
||||
}).then(value =>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="ui-table" :class="{'is-inline': inline }">
|
||||
<header class="ui-table-row ui-table-head">
|
||||
<div v-for="column in columns" :key="column.key" class="ui-table-cell" :table-field="column.field" :style="column.flex">
|
||||
{{ column.label | localize }}
|
||||
<span v-localize="column.label"></span>
|
||||
<button :disabled="!column.canSort" @click="sort(column)" type="button" class="ui-table-sort" :class="tableFilter.orderBy == column.field ? 'sort-' + (tableFilter.orderIsDescending ? 'desc' : 'asc') : null">
|
||||
<i class="arrow arrow-down"></i>
|
||||
</button>
|
||||
@@ -70,8 +70,10 @@
|
||||
export default {
|
||||
name: 'uiTable',
|
||||
|
||||
emits: ['loaded', 'count', 'select'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
config: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => { }
|
||||
@@ -96,15 +98,15 @@
|
||||
components: { UiPagination },
|
||||
|
||||
watch: {
|
||||
'value.columns': function (val)
|
||||
'config.columns': function (val)
|
||||
{
|
||||
this.generateColumns(val);
|
||||
},
|
||||
'value.search': function (val)
|
||||
'config.search': function (val)
|
||||
{
|
||||
this.tableFilter.search = val;
|
||||
},
|
||||
'value.items': function (val)
|
||||
'config.items': function (val)
|
||||
{
|
||||
this.initialize();
|
||||
},
|
||||
@@ -183,7 +185,7 @@
|
||||
{
|
||||
this.debouncedUpdate = _debounce(this.update, 300);
|
||||
|
||||
this.configuration = _extend(JSON.parse(JSON.stringify(defaultConfig)), this.value);
|
||||
this.configuration = _extend(JSON.parse(JSON.stringify(defaultConfig)), this.config);
|
||||
|
||||
this.tableFilter.pageSize = this.configuration.pageSize;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<button type="button" v-for="(tab, index) in tabs" class="ui-tabs-list-item" :key="index" :class="{ 'is-active': tab.active, 'has-errors': tab.hasErrors }" :disabled="tab.disabled"
|
||||
:aria-selected="tab.active" role="tab" @click="select(index)">
|
||||
<i v-if="tab.hasErrors" class="ui-tabs-list-item-error fth-alert-circle"></i>
|
||||
{{ tab.label | localize }}
|
||||
<span v-localize="tab.label"></span>
|
||||
<i v-if="tab.countOutput > 0" class="ui-tabs-list-item-count">{{tab.countOutput}}</i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<component :disabled="value.disabled" :is="tag" type="button" :to="value.url" class="ui-tree-item-link" @click="onClick(value, $event)">
|
||||
<i class="ui-tree-item-icon" :class="value.icon"></i>
|
||||
<i v-if="value.modifier" :title="value.modifier.name" class="ui-tree-item-modifier" :class="value.modifier.icon"></i>
|
||||
<span class="ui-tree-item-text">{{value.name | localize}}</span>
|
||||
<span class="ui-tree-item-text" v-localize="value.name"></span>
|
||||
</component>
|
||||
<ui-dot-button :disabled="value.disabled" class="ui-tree-item-actions" v-if="value.hasActions" @click="onActionsClicked(value, $event)" />
|
||||
</div>
|
||||
@@ -19,6 +19,8 @@
|
||||
export default {
|
||||
name: 'uiTreeItem',
|
||||
|
||||
emits: ['click', 'open', 'rightclick', 'actions'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
export default {
|
||||
name: 'uiTree',
|
||||
|
||||
emits: ['select', 'onStatusChange'],
|
||||
|
||||
props: {
|
||||
depth: {
|
||||
type: Number,
|
||||
@@ -65,7 +67,7 @@
|
||||
computed: {
|
||||
actionsDefined()
|
||||
{
|
||||
return this.$scopedSlots.hasOwnProperty('actions');
|
||||
return typeof this.$slots.actions === 'function';
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
class Plugin
|
||||
{
|
||||
#name;
|
||||
#onMounted;
|
||||
|
||||
routes = [];
|
||||
renderers = {};
|
||||
|
||||
|
||||
constructor(name)
|
||||
{
|
||||
this.#name = name;
|
||||
}
|
||||
|
||||
|
||||
get name()
|
||||
{
|
||||
return this.#name;
|
||||
}
|
||||
|
||||
set mounted(callback)
|
||||
{
|
||||
this.#onMounted = callback;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add a new vue form renderer to the global configuration
|
||||
*/
|
||||
addRenderer(alias, renderer)
|
||||
{
|
||||
this.renderers[alias] = renderer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a new route to vue-router
|
||||
*/
|
||||
addRoute(route)
|
||||
{
|
||||
this.routes.push(route);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a new route to vue-router
|
||||
*/
|
||||
addRoutes(routes)
|
||||
{
|
||||
routes.forEach(route =>
|
||||
{
|
||||
this.routes.push(route);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default Plugin;
|
||||
@@ -1,12 +1,4 @@
|
||||
|
||||
//import Date from './date';
|
||||
//import Localize from './localize';
|
||||
//import Resizable from './resizable';
|
||||
//import Clickoutside from './clickoutside';
|
||||
//import Filesize from './filesize';
|
||||
//import Currency from './currency';
|
||||
//import Sortable from './sortable';
|
||||
|
||||
export default function (app)
|
||||
{
|
||||
const requireComponent = require.context('.', true, /[\w-]+\.js/);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
export default {
|
||||
name: 'uiEditorComponent',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [ Object, Array ]
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
export default {
|
||||
name: 'uiEditor',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
config: {
|
||||
type: [ String, Object ],
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Array]
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
import LanguagesApi from 'zero/resources/languages';
|
||||
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
import LanguagesApi from 'zero/resources/languages';
|
||||
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Array],
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Object, Array]
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
components: { UiEditor },
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [Array, Object]
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
export default {
|
||||
name: 'uiSelect',
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number, Object],
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [ String, Number ]
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits: ['input'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
import './localize';
|
||||
@@ -1,10 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
import Localization from 'zero/services/localization';
|
||||
|
||||
/// <summary>
|
||||
/// Localizes the given property and sets the inner-text of the node to its result
|
||||
/// </summary>
|
||||
Vue.filter('localize', (value, options) =>
|
||||
{
|
||||
return Localization.localize(value, options);
|
||||
});
|
||||
@@ -19,14 +19,12 @@
|
||||
<template v-for="section in sections">
|
||||
<router-link :to="section.url" class="app-nav-item" :alias="section.alias" :class="{ 'has-children': hasChildren(section) }">
|
||||
<i class="app-nav-item-icon" :class="section.icon"></i>
|
||||
{{section.name | localize}}
|
||||
<span v-localize="section.name"></span>
|
||||
<i v-if="hasChildren(section)" class="app-nav-item-arrow fth-chevron-down"></i>
|
||||
</router-link>
|
||||
<transition name="app-nav-children">
|
||||
<div class="app-nav-children" v-if="hasChildren(section) && $route.path.indexOf('/' + section.alias) === 0">
|
||||
<router-link v-for="child in section.children" v-bind:key="child.alias" :to="child.url" class="app-nav-child">
|
||||
{{child.name | localize}}
|
||||
</router-link>
|
||||
<router-link v-for="child in section.children" v-bind:key="child.alias" :to="child.url" class="app-nav-child" v-localize="child.name" />
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
onSubmit(form)
|
||||
{
|
||||
this.rejectReason = null;
|
||||
|
||||
console.info(form);
|
||||
form.handle(AuthApi.login(this.model)).then(res =>
|
||||
{
|
||||
window.location.reload();
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
disabled: Boolean
|
||||
},
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
data: () => ({
|
||||
icons: {
|
||||
image: 'fth-image',
|
||||
|
||||
@@ -8,19 +8,23 @@
|
||||
<code>{{path}}</code>
|
||||
</p>
|
||||
<ui-button class="page-error-button" type="light onbg" :label="detailsText" @click="details = !details" />
|
||||
<template v-if="details">
|
||||
<div v-if="details">
|
||||
<br><br>
|
||||
<div class="page-error-routes">
|
||||
<span>#</span>
|
||||
<span>Name</span>
|
||||
<span>Path</span>
|
||||
<template v-for="(route, index) in routes">
|
||||
<span>{{index + 1}}.</span>
|
||||
<b>{{route.name}}</b>
|
||||
<span>{{route.path}}</span>
|
||||
</template>
|
||||
<header class="page-error-route is-head">
|
||||
<span>#</span>
|
||||
<b>Name</b>
|
||||
<span>Path</span>
|
||||
</header>
|
||||
<div>
|
||||
<div class="page-error-route" v-for="(route, index) in routes">
|
||||
<span>{{index + 1}}.</span>
|
||||
<b>{{route.name}}</b>
|
||||
<span>{{route.path}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -57,10 +61,10 @@
|
||||
|
||||
rebuild()
|
||||
{
|
||||
this.path = this.$router.options.base + this.$route.path.substring(1);
|
||||
this.path = this.$router.options.history.base + this.$route.path;
|
||||
this.routes = [];
|
||||
|
||||
this.$router.options.routes.forEach(route =>
|
||||
this.$router.getRoutes().forEach(route =>
|
||||
{
|
||||
this.routes.push({
|
||||
path: route.path,
|
||||
@@ -128,9 +132,8 @@
|
||||
}
|
||||
|
||||
.page-error-routes
|
||||
{
|
||||
display: grid;
|
||||
grid-template-columns: auto auto 1fr;
|
||||
{
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
text-align: left;
|
||||
@@ -153,4 +156,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-error-route
|
||||
{
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 3fr 6fr;
|
||||
}
|
||||
</style>
|
||||
@@ -8,7 +8,7 @@
|
||||
<button type="button" v-for="item in pageTypes" class="page-create-item" @click="onSelect(item)">
|
||||
<i class="page-create-item-icon" :class="item.icon"></i>
|
||||
<span class="page-create-item-text">
|
||||
{{item.name | localize}}
|
||||
<span v-localize="item.name"></span>
|
||||
<span v-if="item.description" v-localize="item.description"></span>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
},
|
||||
},
|
||||
|
||||
emits: ['input'],
|
||||
|
||||
data: () => ({
|
||||
features: []
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="apps-items">
|
||||
<router-link v-for="app in value" :key="app.id" :to="getAppLink(app)" class="apps-item">
|
||||
<router-link v-for="app in items" :key="app.id" :to="getAppLink(app)" class="apps-item">
|
||||
<strong class="apps-item-name">{{app.name}}</strong>
|
||||
<span class="apps-item-minor">{{app.domains[0]}}</span>
|
||||
<span class="apps-item-status" :class="{ 'is-active': app.isActive }" v-localize="getStatus(app)"></span>
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
items: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<div class="apps">
|
||||
<ui-header-bar title="@application.list" :count="count" :back-button="true" />
|
||||
<div class="ui-blank-box">
|
||||
<applications-items v-model="apps" />
|
||||
<applications-items v-model:items="apps" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<strong v-localize="item.name"></strong>
|
||||
<template v-if="item.description">
|
||||
<br>
|
||||
{{item.description | localize({ tokens: tokens })}}
|
||||
<span v-localize="{ key: item.description, tokens: tokens }"></span>
|
||||
</template>
|
||||
</p>
|
||||
</router-link>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import Plugin from 'zero/core/plugin';
|
||||
|
||||
|
||||
let plugin = new Plugin('zero');
|
||||
|
||||
plugin.mounted = () =>
|
||||
{
|
||||
console.info(this.name + ' mounted');
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
zero.renderers = zero.renderers || {};
|
||||
|
||||
// https://webpack.js.org/guides/dependency-management/#require-context
|
||||
const requireComponent = require.context(
|
||||
// Look for files in the current directory
|
||||
'.',
|
||||
// Do look in subdirectories
|
||||
true,
|
||||
// .js files
|
||||
/[\w-]+\.js/
|
||||
);
|
||||
|
||||
// For each matching file name...
|
||||
requireComponent.keys().forEach((path) =>
|
||||
{
|
||||
let pathParts = path.split('/');
|
||||
let fileName = pathParts[pathParts.length - 1];
|
||||
|
||||
if (fileName === 'globals.js')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const componentConfig = requireComponent(path);
|
||||
const alias = componentConfig.default.alias;
|
||||
|
||||
zero.renderers[alias] = componentConfig.default;
|
||||
});
|
||||
|
||||
// load renderers from plugins
|
||||
// TODO use correct paths for sure
|
||||
//const pluginrenderers = require.context('@/../zero.commerce/plugin', true, /renderers\.js$/);
|
||||
|
||||
//// for each matching file name...
|
||||
//pluginrenderers.keys().foreach((path) =>
|
||||
//{
|
||||
// let pathparts = path.split('/');
|
||||
|
||||
// const componentconfig = pluginrenderers(path);
|
||||
// const alias = componentconfig.default.alias;
|
||||
|
||||
// zero.renderers[alias] = componentconfig.default;
|
||||
//});
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
zero.renderers = zero.renderers || {};
|
||||
|
||||
export default function (app)
|
||||
{
|
||||
const requireComponent = require.context('.', true, /[\w-]+\.js/);
|
||||
|
||||
requireComponent.keys().forEach(path =>
|
||||
{
|
||||
let pathParts = path.split('/');
|
||||
let fileName = pathParts[pathParts.length - 1].split('.')[0];
|
||||
|
||||
if (fileName === 'register')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const componentConfig = requireComponent(path);
|
||||
const config = componentConfig.default || componentConfig;
|
||||
const alias = config.alias;
|
||||
|
||||
zero.renderers[alias] = config;
|
||||
});
|
||||
};
|
||||
@@ -123,27 +123,9 @@ routes.push({ name: '404', path: '/:pathMatch(.*)*', component: () => import('ze
|
||||
|
||||
|
||||
|
||||
|
||||
// create the router with history mode
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: routes,
|
||||
base: zero.path,
|
||||
linkActiveClass: 'is-active',
|
||||
linkExactActiveClass: 'is-active-exact',
|
||||
scrollBehavior(to, from, savedPosition)
|
||||
{
|
||||
return savedPosition ? savedPosition : { x: 0, y: 0 };
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
// set meta title before routing
|
||||
|
||||
router.beforeEach((to, from, next) =>
|
||||
const beforeEach = (to, from, next) =>
|
||||
{
|
||||
let isGuarded = false;
|
||||
|
||||
@@ -201,7 +183,19 @@ router.beforeEach((to, from, next) =>
|
||||
{
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export default router;
|
||||
|
||||
// create the router with history mode
|
||||
export default createRouter({
|
||||
history: createWebHistory(zero.path),
|
||||
routes: routes,
|
||||
linkActiveClass: 'is-active',
|
||||
linkExactActiveClass: 'is-active-exact',
|
||||
beforeEach: beforeEach,
|
||||
scrollBehavior(to, from, savedPosition)
|
||||
{
|
||||
return savedPosition ? savedPosition : { x: 0, y: 0 };
|
||||
}
|
||||
});
|
||||
@@ -1,5 +1,47 @@
|
||||
import mitt from 'mitt';
|
||||
|
||||
const emitter = mitt();
|
||||
let handlers = new Map();
|
||||
|
||||
export default emitter;
|
||||
/*
|
||||
* Adds a new handler for an event of a specfic type
|
||||
*/
|
||||
const on = (type, handler) =>
|
||||
{
|
||||
const typeHandlers = handlers.get(type);
|
||||
const added = typeHandlers && typeHandlers.push(handler);
|
||||
|
||||
if (!added)
|
||||
{
|
||||
handlers.set(type, [handler]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Removes a specifc event handler
|
||||
*/
|
||||
const off = (type, handler) =>
|
||||
{
|
||||
const typeHandlers = handlers.get(type);
|
||||
|
||||
if (typeHandlers)
|
||||
{
|
||||
typeHandlers.splice(typeHandlers.indexOf(handler) >>> 0, 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Adds a new handler for an event of a specfic type
|
||||
*/
|
||||
const emit = (type, event) =>
|
||||
{
|
||||
(handlers.get(type) || []).slice().map(handler => handler(event));
|
||||
(handlers.get('*') || []).slice().map(handler => handler(type, event));
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
on,
|
||||
off,
|
||||
emit
|
||||
};
|
||||
@@ -1,86 +1,83 @@
|
||||
import Vue from 'vue';
|
||||
import Strings from 'zero/services/strings';
|
||||
import { find as _find, extend as _extend } from 'underscore';
|
||||
|
||||
export default new Vue({
|
||||
let instances = [];
|
||||
|
||||
data: () => ({
|
||||
instances: []
|
||||
}),
|
||||
|
||||
methods: {
|
||||
|
||||
success(label, text, options)
|
||||
{
|
||||
this.show(_extend({
|
||||
type: 'success',
|
||||
label: label,
|
||||
text: text
|
||||
}, options || {}));
|
||||
},
|
||||
const success = (label, text, options) =>
|
||||
{
|
||||
show(_extend({
|
||||
type: 'success',
|
||||
label: label,
|
||||
text: text
|
||||
}, options || {}));
|
||||
};
|
||||
|
||||
|
||||
error(label, text, options)
|
||||
{
|
||||
this.show(_extend({
|
||||
type: 'error',
|
||||
label: label,
|
||||
text: text
|
||||
}, options || {}));
|
||||
},
|
||||
const error = (label, text, options) =>
|
||||
{
|
||||
show(_extend({
|
||||
type: 'error',
|
||||
label: label,
|
||||
text: text
|
||||
}, options || {}));
|
||||
};
|
||||
|
||||
|
||||
show(options, text)
|
||||
{
|
||||
let me = this;
|
||||
|
||||
if (typeof options === 'string')
|
||||
{
|
||||
options = {
|
||||
label: options,
|
||||
text: text
|
||||
};
|
||||
}
|
||||
|
||||
options = _extend({
|
||||
id: Strings.guid(),
|
||||
type: 'default',
|
||||
label: null,
|
||||
text: null,
|
||||
persistent: false,
|
||||
duration: 3000,
|
||||
timeout: null,
|
||||
close: () =>
|
||||
{
|
||||
clearTimeout(options.timeout);
|
||||
me.close(this.instances.indexOf(options));
|
||||
}
|
||||
}, options);
|
||||
|
||||
if (!options.label && !options.text)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
options.timeout = setTimeout(() =>
|
||||
{
|
||||
options.close();
|
||||
}, options.duration);
|
||||
|
||||
this.instances.push(options);
|
||||
},
|
||||
|
||||
|
||||
close(index)
|
||||
{
|
||||
if (index > -1)
|
||||
{
|
||||
this.instances.splice(index, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.instances = [];
|
||||
}
|
||||
}
|
||||
const show = (options, text) =>
|
||||
{
|
||||
if (typeof options === 'string')
|
||||
{
|
||||
options = {
|
||||
label: options,
|
||||
text: text
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
options = _extend({
|
||||
id: Strings.guid(),
|
||||
type: 'default',
|
||||
label: null,
|
||||
text: null,
|
||||
persistent: false,
|
||||
duration: 3000,
|
||||
timeout: null,
|
||||
close: () =>
|
||||
{
|
||||
clearTimeout(options.timeout);
|
||||
close(instances.indexOf(options));
|
||||
}
|
||||
}, options);
|
||||
|
||||
if (!options.label && !options.text)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
options.timeout = setTimeout(() =>
|
||||
{
|
||||
options.close();
|
||||
}, options.duration);
|
||||
|
||||
instances.push(options);
|
||||
};
|
||||
|
||||
|
||||
const close = index =>
|
||||
{
|
||||
if (index > -1)
|
||||
{
|
||||
instances.splice(index, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
instances = [];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
success,
|
||||
error,
|
||||
show,
|
||||
close
|
||||
};
|
||||
+122
-128
@@ -1,134 +1,128 @@
|
||||
import { createApp } from 'vue';
|
||||
import AppConfirm from 'zero/components/overlays/confirm';
|
||||
import Strings from 'zero/services/strings';
|
||||
import EventHub from 'zero/services/eventhub';
|
||||
import { find as _find, extend as _extend } from 'underscore';
|
||||
|
||||
export default createApp({
|
||||
|
||||
data: () => ({
|
||||
dropdownInstance: null,
|
||||
instances: []
|
||||
}),
|
||||
|
||||
methods: {
|
||||
|
||||
// sets a new active dropdown so the old one gets auto-closed
|
||||
setDropdown(instance)
|
||||
{
|
||||
if (this.dropdownInstance != null)
|
||||
{
|
||||
this.dropdownInstance.hide();
|
||||
}
|
||||
|
||||
this.dropdownInstance = instance;
|
||||
},
|
||||
|
||||
// open a deletion confirm dialog with the given options
|
||||
confirmDelete(title, text)
|
||||
{
|
||||
let options = _extend({
|
||||
title: typeof title === 'string' ? title : '@deleteoverlay.title',
|
||||
text: text || '@deleteoverlay.text',
|
||||
confirmLabel: '@deleteoverlay.confirm',
|
||||
confirmType: 'danger',
|
||||
closeLabel: '@deleteoverlay.close',
|
||||
component: AppConfirm,
|
||||
autoclose: false,
|
||||
softdismiss: false
|
||||
}, typeof title === 'object' ? title : {});
|
||||
|
||||
return this.open(options);
|
||||
},
|
||||
|
||||
// open a confirm dialog with the given options
|
||||
confirm(title, text)
|
||||
{
|
||||
let options = _extend({
|
||||
title: title,
|
||||
text: text,
|
||||
component: AppConfirm,
|
||||
autoclose: true,
|
||||
softdismiss: false
|
||||
}, typeof title === 'object' ? title : {});
|
||||
|
||||
return this.open(options);
|
||||
},
|
||||
|
||||
|
||||
// opens an overlay
|
||||
open(options)
|
||||
{
|
||||
const defaultWidth = options.display === 'editor' ? 560 : 460;
|
||||
|
||||
options = _extend({
|
||||
id: Strings.guid(),
|
||||
display: 'dialog',
|
||||
width: defaultWidth,
|
||||
hide: this.close,
|
||||
autoclose: true,
|
||||
softdismiss: options.display !== 'editor',
|
||||
closeLabel: '@ui.close',
|
||||
confirmLabel: '@ui.confirm',
|
||||
confirmType: 'default'
|
||||
}, options);
|
||||
|
||||
options.theme = 'default';
|
||||
|
||||
this.instances.push(options);
|
||||
|
||||
return new Promise((resolve, reject) =>
|
||||
{
|
||||
options.close = () =>
|
||||
{
|
||||
this.close(options);
|
||||
reject(options);
|
||||
};
|
||||
options.confirm = data =>
|
||||
{
|
||||
if (options.autoclose)
|
||||
{
|
||||
this.close(options);
|
||||
}
|
||||
resolve(data, options);
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
// closes an overlay
|
||||
close(instance)
|
||||
{
|
||||
if (this.instances.length < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!instance)
|
||||
{
|
||||
this.instances.pop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof instance === 'string')
|
||||
{
|
||||
instance = _find(this.instances, item => item.id === instance);
|
||||
}
|
||||
|
||||
if (instance)
|
||||
{
|
||||
const index = this.instances.indexOf(instance);
|
||||
this.instances.splice(index, 1);
|
||||
}
|
||||
},
|
||||
|
||||
// closes all overlays
|
||||
closeAll()
|
||||
{
|
||||
this.instances.forEach(instance =>
|
||||
{
|
||||
|
||||
});
|
||||
}
|
||||
let currentInstance = null;
|
||||
let instances = [];
|
||||
|
||||
// sets a new active dropdown so the old one gets auto-closed
|
||||
const setDropdown = instance =>
|
||||
{
|
||||
if (currentInstance != null)
|
||||
{
|
||||
currentInstance.hide();
|
||||
}
|
||||
});
|
||||
|
||||
currentInstance = instance;
|
||||
};
|
||||
|
||||
// open a deletion confirm dialog with the given options
|
||||
const confirmDelete = (title, text) =>
|
||||
{
|
||||
let options = _extend({
|
||||
title: typeof title === 'string' ? title : '@deleteoverlay.title',
|
||||
text: text || '@deleteoverlay.text',
|
||||
confirmLabel: '@deleteoverlay.confirm',
|
||||
confirmType: 'danger',
|
||||
closeLabel: '@deleteoverlay.close',
|
||||
component: AppConfirm,
|
||||
autoclose: false,
|
||||
softdismiss: false
|
||||
}, typeof title === 'object' ? title : {});
|
||||
|
||||
return open(options);
|
||||
};
|
||||
|
||||
// open a confirm dialog with the given options
|
||||
const confirm = (title, text) =>
|
||||
{
|
||||
let options = _extend({
|
||||
title: title,
|
||||
text: text,
|
||||
component: AppConfirm,
|
||||
autoclose: true,
|
||||
softdismiss: false
|
||||
}, typeof title === 'object' ? title : {});
|
||||
|
||||
return open(options);
|
||||
};
|
||||
|
||||
|
||||
// opens an overlay
|
||||
const open = options =>
|
||||
{
|
||||
const defaultWidth = options.display === 'editor' ? 560 : 460;
|
||||
|
||||
options = _extend({
|
||||
id: Strings.guid(),
|
||||
display: 'dialog',
|
||||
width: defaultWidth,
|
||||
hide: close,
|
||||
autoclose: true,
|
||||
softdismiss: options.display !== 'editor',
|
||||
closeLabel: '@ui.close',
|
||||
confirmLabel: '@ui.confirm',
|
||||
confirmType: 'default'
|
||||
}, options);
|
||||
|
||||
options.theme = 'default';
|
||||
|
||||
instances.push(options);
|
||||
EventHub.emit('overlay:open', instances);
|
||||
|
||||
return new Promise((resolve, reject) =>
|
||||
{
|
||||
options.close = () =>
|
||||
{
|
||||
close(options);
|
||||
reject(options);
|
||||
};
|
||||
options.confirm = data =>
|
||||
{
|
||||
if (options.autoclose)
|
||||
{
|
||||
close(options);
|
||||
}
|
||||
resolve(data, options);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// closes an overlay
|
||||
const close = instance =>
|
||||
{
|
||||
if (instances.length < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!instance)
|
||||
{
|
||||
instances.pop();
|
||||
EventHub.emit('overlay:close', instances);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof instance === 'string')
|
||||
{
|
||||
instance = _find(instances, item => item.id === instance);
|
||||
}
|
||||
|
||||
if (instance)
|
||||
{
|
||||
const index = instances.indexOf(instance);
|
||||
instances.splice(index, 1);
|
||||
EventHub.emit('overlay:close', instances);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
setDropdown,
|
||||
confirmDelete,
|
||||
confirm,
|
||||
open,
|
||||
close
|
||||
};
|
||||
+10
-7
@@ -6,17 +6,20 @@ zero.apps = {
|
||||
};
|
||||
|
||||
import Router from 'zero/router.config.js';
|
||||
//import 'zero/components/globals';
|
||||
import registerComponents from 'zero/components/register';
|
||||
import registerDirectives from 'zero/directives/register';
|
||||
//import 'zero/filters/globals';
|
||||
//import 'zero/renderers/globals';
|
||||
//import 'zero/pages/register';
|
||||
import registerRenderers from 'zero/renderers/register';
|
||||
|
||||
//import 'zero/zero.plugins.js';
|
||||
import 'zero/zero.plugins.js';
|
||||
//import ZeroPlugin from 'zero/plugin.js';
|
||||
|
||||
const app = createApp(App);
|
||||
app.use(Router);
|
||||
registerDirectives(app);
|
||||
|
||||
console.info(app);
|
||||
registerDirectives(app);
|
||||
registerComponents(app);
|
||||
registerRenderers(app);
|
||||
|
||||
app.mount('#app');
|
||||
|
||||
//console.info(ZeroPlugin);
|
||||
@@ -14,7 +14,6 @@
|
||||
"dayjs": "^1.8.26",
|
||||
"flatpickr": "^4.6.3",
|
||||
"lodash": "*",
|
||||
"mitt": "^2.1.0",
|
||||
"sortablejs": "^1.10.2",
|
||||
"underscore": "^1.10.2",
|
||||
"vue": "3.0.0",
|
||||
|
||||
Reference in New Issue
Block a user