Fix panel init

This commit is contained in:
rijkvanzanten
2021-06-11 21:38:20 -04:00
parent 8c7abba300
commit e77e532ef6
8 changed files with 62 additions and 63 deletions

View File

@@ -9,7 +9,7 @@ const router = Router();
const extensionsPath = env.EXTENSIONS_PATH as string;
const appExtensions = ['interfaces', 'layouts', 'displays', 'modules'];
const appExtensions = ['interfaces', 'layouts', 'displays', 'modules', 'panels'];
router.get(
['/:type', '/:type/*'],

View File

@@ -5,6 +5,7 @@ import App from './app.vue';
import { registerComponents } from './components/register';
import { DIRECTUS_LOGO } from './constants';
import { registerDirectives } from './directives/register';
import { registerPanels } from './panels/register';
import { registerDisplays } from './displays/register';
import { registerInterfaces } from './interfaces/register';
import { i18n } from './lang/';
@@ -40,7 +41,13 @@ async function init() {
registerComponents(app);
registerViews(app);
await Promise.all([registerInterfaces(app), registerDisplays(app), registerLayouts(app), loadModules()]);
await Promise.all([
registerInterfaces(app),
registerPanels(app),
registerDisplays(app),
registerLayouts(app),
loadModules(),
]);
app.mount('#app');

View File

@@ -1,5 +1,5 @@
<template>
<v-dialog :active="active" @toggle="$emit('toggle', $event)" persistent @esc="cancel">
<v-dialog :model-value="active" @update:modelValue="$emit('toggle', $event)" persistent @esc="cancel">
<template #activator="slotBinding">
<slot name="activator" v-bind="slotBinding" />
</template>

View File

@@ -45,7 +45,7 @@
</template>
<v-list>
<v-list-item @click="editDashboard = item" class="warning">
<v-list-item @click="editDashboard = item" class="warning" clickable>
<v-list-item-icon>
<v-icon name="edit" outline />
</v-list-item-icon>
@@ -54,7 +54,7 @@
</v-list-item-content>
</v-list-item>
<v-list-item @click="confirmDelete = item.id" class="danger">
<v-list-item @click="confirmDelete = item.id" class="danger" clickable>
<v-list-item-icon>
<v-icon name="delete" outline />
</v-list-item-icon>
@@ -71,7 +71,7 @@
{{ t('no_dashboards_copy') }}
</v-info>
<v-dialog :active="!!confirmDelete" @esc="confirmDelete = null">
<v-dialog :model-value="!!confirmDelete" @esc="confirmDelete = null">
<v-card>
<v-card-title>{{ t('dashboard_delete_confirm') }}</v-card-title>
@@ -79,7 +79,7 @@
<v-button @click="confirmDelete = null" secondary>
{{ t('cancel') }}
</v-button>
<v-button class="action-delete" @click="deleteDashboard" :loading="deletingDashboard">
<v-button danger @click="deleteDashboard" :loading="deletingDashboard">
{{ t('delete') }}
</v-button>
</v-card-actions>
@@ -183,13 +183,6 @@ export default defineComponent({
padding-top: 0;
}
.action-delete {
--v-button-background-color: var(--danger-10);
--v-button-color: var(--danger);
--v-button-background-color-hover: var(--danger-25);
--v-button-color-hover: var(--danger);
}
.ctx-toggle {
--v-icon-color: var(--foreground-subdued);
--v-icon-color-hover: var(--foreground-normal);

View File

@@ -1,5 +1,10 @@
<template>
<v-drawer active :title="(panel && panel.name) || t('panel')" @cancel="$emit('cancel')" icon="insert_chart">
<v-drawer
:model-value="true"
:title="(panel && panel.name) || t('panel')"
@cancel="$emit('cancel')"
icon="insert_chart"
>
<template #actions>
<v-button :disabled="!edits.type" @click="emitSave" icon rounded v-tooltip.bottom="t('done')">
<v-icon name="check" />
@@ -50,12 +55,21 @@
<div class="field half-left">
<p class="type-label">{{ t('icon') }}</p>
<interface-select-icon v-model="edits.icon" :disabled="edits.show_header !== true" />
<interface-select-icon
:value="edits.icon"
@input="edits.icon = $event"
:disabled="edits.show_header !== true"
/>
</div>
<div class="field half-right">
<p class="type-label">{{ t('color') }}</p>
<interface-select-color v-model="edits.color" :disabled="edits.show_header !== true" width="half" />
<interface-select-color
:value="edits.color"
@input="edits.color = $event"
:disabled="edits.show_header !== true"
width="half"
/>
</div>
<div class="field full">

View File

@@ -1,17 +1,9 @@
import { ref, Ref } from 'vue';
import { shallowRef, Ref } from 'vue';
import { PanelConfig } from './types';
let panelsRaw: Ref<PanelConfig[]>;
let panels: Ref<PanelConfig[]>;
export function getPanels(): Record<string, Ref<PanelConfig[]>> {
if (!panelsRaw) {
panelsRaw = ref([]);
}
if (!panels) {
panels = ref([]);
}
const panelsRaw: Ref<PanelConfig[]> = shallowRef([]);
const panels: Ref<PanelConfig[]> = shallowRef([]);
export function getPanels(): { panels: Ref<PanelConfig[]>; panelsRaw: Ref<PanelConfig[]> } {
return { panels, panelsRaw };
}

View File

@@ -1,47 +1,40 @@
// import api from '@/api';
// import { getRootPath } from '@/utils/get-root-path';
import registerComponent from '@/utils/register-component/';
// import asyncPool from 'tiny-async-pool';
import { Component } from 'vue';
import api from '@/api';
import { getRootPath } from '@/utils/get-root-path';
import { asyncPool } from '@/utils/async-pool';
import { App } from 'vue';
import { getPanels } from './index';
import { PanelConfig } from './types';
const { panelsRaw } = getPanels();
export async function registerPanels(): Promise<void> {
const context = require.context('.', true, /^.*index\.ts$/);
export async function registerPanels(app: App): Promise<void> {
const panelModules = import.meta.globEager('./*/**/index.ts');
const modules = context
.keys()
.map((key) => context(key))
.map((mod) => mod.default)
.filter((m) => m);
const panels: PanelConfig[] = Object.values(panelModules).map((module) => module.default);
// try {
// const customResponse = await api.get('/extensions/panels/');
// const panels: string[] = customResponse.data.data || [];
try {
const customResponse = await api.get('/extensions/panels/');
const customPanels: string[] = customResponse.data.data || [];
// await asyncPool(5, panels, async (panelName) => {
// try {
// const result = await import(
// /* webpackIgnore: true */ getRootPath() + `extensions/panels/${panelName}/index.js`
// );
// modules.push(result.default);
// } catch (err) {
// console.warn(`Couldn't load custom panel "${panelName}":`, err);
// }
// });
// } catch {
// console.warn(`Couldn't load custom panels`);
// }
await asyncPool(5, customPanels, async (panelName) => {
try {
const result = await import(/* @vite-ignore */ `${getRootPath()}extensions/panels/${panelName}/index.js`);
panels.push(result.default);
} catch (err) {
console.warn(`Couldn't load custom panel "${panelName}":`, err);
}
});
} catch {
console.warn(`Couldn't load custom panels`);
}
panelsRaw.value = modules;
panelsRaw.value = panels;
panelsRaw.value.forEach((panel: PanelConfig) => {
registerComponent('panel-' + panel.id, panel.component);
app.component('panel-' + panel.id, panel.component);
if (typeof panel.options !== 'function' && Array.isArray(panel.options) === false) {
registerComponent(`panel-options-${panel.id}`, panel.options as Component);
app.component(`panel-options-${panel.id}`, panel.options);
}
});
}

View File

@@ -1,5 +1,5 @@
import { Field } from '@/types';
import { AsyncComponent, Component } from 'vue';
import { Component } from 'vue';
import VueI18n from 'vue-i18n';
export interface PanelConfig {
@@ -7,8 +7,8 @@ export interface PanelConfig {
name: string;
icon: string;
description?: string | VueI18n.TranslateResult;
component: Component | AsyncComponent;
options: DeepPartial<Field>[] | Component | AsyncComponent;
component: Component;
options: DeepPartial<Field>[] | Component;
minWidth: number;
minHeight: number;
}