Allow multiple widgets and minor improvements

* Allow mulitple widgets for plugins, allow setting required permissions
* Split datetime formatter code for reuse
This commit is contained in:
Ferdinand Thiessen 2020-11-13 04:01:53 +01:00
parent 7b1a1c3656
commit 19f91d2abf
9 changed files with 67 additions and 52 deletions

View File

@ -1,5 +1,4 @@
{
"editor.formatOnPaste": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true

View File

@ -1,25 +1,7 @@
import { boot } from 'quasar/wrappers';
import { formatDateTime } from 'src/utils/datetime';
export default boot(({ Vue }) => {
function formatDateTime(
date: Date,
useDate = true,
useTime = false,
useSeconds = false,
useWeekday = false
) {
const dateTimeFormat = new Intl.DateTimeFormat([], {
year: useDate ? 'numeric' : undefined,
month: useDate ? '2-digit' : undefined,
day: useDate ? '2-digit' : undefined,
weekday: useWeekday ? 'long' : undefined,
hour: useTime ? '2-digit' : undefined,
minute: useTime ? '2-digit' : undefined,
second: useTime && useSeconds ? '2-digit' : undefined
});
return dateTimeFormat.format(date);
}
Vue.filter('date', formatDateTime);
Vue.filter('time', (date: Date, seconds = false) =>
formatDateTime(date, false, true, seconds)

View File

@ -23,9 +23,7 @@ function combineRoutes(
): RouteConfig[] {
target.forEach(target => {
if (target.path === mainPath) {
console.log('target', target.path);
source.forEach((sourceMainConfig: FG_Plugin.PluginRouteConfig) => {
console.log('sourceMainconfig', sourceMainConfig);
const targetMainConfig = target.children?.find(
(targetMainConfig: RouteConfig) => {
return sourceMainConfig.path === targetMainConfig.path;
@ -164,12 +162,13 @@ function loadPlugin(
plugin.outRoutes
);
}
if (plugin.widget) {
loadedPlugins.widgets.push(plugin.widget);
if (plugin.widgets.length > 0) {
plugin.widgets.forEach(
widget => (widget.name = plugin.name + '_' + widget.name)
);
Array.prototype.push.apply(loadedPlugins.widgets, plugin.widgets);
}
if (plugin.store) {
console.log(plugin.store);
console.log(plugin.store.keys());
plugin.store.forEach((store_plugin, store_namespace) => {
store.registerModule(store_namespace, store_plugin);
});

View File

@ -16,21 +16,24 @@
<script lang="ts">
import { defineComponent, onMounted, ref } from '@vue/composition-api';
import { hasPermissions } from 'src/components/permission';
import { AsyncComponentPromise } from 'vue/types/options';
export default defineComponent({
name: 'Dashboard',
setup(_, { root }) {
const widgets = ref<Array<AsyncComponentPromise>>([]);
onMounted(() => {
console.log('mounted!');
root.$flaschengeistPlugins.widgets.forEach(widget =>
widgets.value.push(widget.widget)
);
root.$flaschengeistPlugins.widgets.forEach((widget) => {
if (hasPermissions(widget.permissions, root.$store))
widgets.value.push(widget.widget);
});
});
return {
widgets
widgets,
};
}
},
});
</script>

18
src/plugins.d.ts vendored
View File

@ -18,14 +18,21 @@ declare namespace FG_Plugin {
meta?: { permissions?: string[] };
}
interface Widget {
name: string;
priority: number;
permissions: FG.Permission[];
widget: AsyncComponentPromise;
}
interface Plugin {
name: string;
version: string;
widgets: Widget[];
requiredModules: string[];
mainRoutes?: PluginRouteConfig[];
outRoutes?: PluginRouteConfig[];
store?: Map<string, Module<any, StateInterface>>;
widget?: Widget;
requiredModules: string[];
version: string;
}
interface PluginMainLink extends PluginChildLink {
@ -45,11 +52,6 @@ declare namespace FG_Plugin {
version: string;
}
interface Widget {
widget: AsyncComponentPromise;
priority: number;
}
interface LoadedPlugins {
plugins: LoadedPlugin[];
routes: RouteConfig[];

View File

@ -12,10 +12,14 @@ const plugin: FG_Plugin.Plugin = {
store: new Map<string, Module<BalanceInterface, StateInterface>>([
['balance', balance]
]),
widget: {
widget: () => import('./components/Widget.vue'),
priority: 0
}
widgets: [
{
priority: 0,
name: 'current',
permissions: ['balance_show'],
widget: () => import('./components/Widget.vue')
}
]
};
export default plugin;

View File

@ -4,10 +4,14 @@ const plugin: FG_Plugin.Plugin = {
name: 'Schedule',
requiredModules: [],
version: '0.0.1',
widget: {
widget: () => import('./components/Widget.vue'),
priority: 0
}
widgets: [
{
priority: 0,
name: 'stats',
permissions: [],
widget: () => import('./components/Widget.vue')
}
]
};
export default plugin;

View File

@ -14,10 +14,14 @@ const plugin: FG_Plugin.Plugin = {
['user', userStore],
['session', sessionsStore]
]),
widget: {
priority: 1,
widget: () => import('./components/Widget.vue')
}
widgets: [
{
priority: 1,
name: 'greeting',
permissions: [],
widget: () => import('./components/Widget.vue')
}
]
};
export default plugin;

18
src/utils/datetime.ts Normal file
View File

@ -0,0 +1,18 @@
export function formatDateTime(
date: Date,
useDate = true,
useTime = false,
useSeconds = false,
useWeekday = false
) {
const dateTimeFormat = new Intl.DateTimeFormat([], {
year: useDate ? 'numeric' : undefined,
month: useDate ? '2-digit' : undefined,
day: useDate ? '2-digit' : undefined,
weekday: useWeekday ? 'long' : undefined,
hour: useTime ? '2-digit' : undefined,
minute: useTime ? '2-digit' : undefined,
second: useTime && useSeconds ? '2-digit' : undefined
});
return dateTimeFormat.format(date);
}