diff --git a/app/controllers/stock_images.php b/app/controllers/stock_images.php index 46954343926e418ad7f5b127dafc50066a634fa0..5ffc6a02c411920305ed30b8ec4e610c9630d9a3 100644 --- a/app/controllers/stock_images.php +++ b/app/controllers/stock_images.php @@ -22,6 +22,10 @@ class StockImagesController extends AuthenticatedController */ public function index_action(): void { + $this->render_vue_app( + Studip\VueApp::create('stock-images/Page') + ->withPlugin('StockImagesPlugin', 'stock-images') + ); } /** diff --git a/lib/classes/VueApp.php b/lib/classes/VueApp.php index 0e209615f1790f3876a8f2fc4b6bee34090f8f42..3ebae34de1b097c717b36dbb86d637142d819052 100644 --- a/lib/classes/VueApp.php +++ b/lib/classes/VueApp.php @@ -38,6 +38,7 @@ final class VueApp implements Stringable return new self($base_component); } + private array $plugins = []; private array $props = []; private array $stores = []; private array $storeData = []; @@ -129,6 +130,27 @@ final class VueApp implements Stringable return $this->storeData; } + /** + * Adds a plugin + * + * You may specify a different filename for the plugin. + */ + public function withPlugin(string $plugin, string $filename = null): VueApp + { + $clone = clone $this; + $clone->plugins[$plugin] = $filename ?? $plugin; + + return $clone; + } + + /** + * Returns all plugins + */ + public function getPlugins(): array + { + return $this->plugins; + } + /** * Returns the template to render the vue app */ @@ -142,6 +164,10 @@ final class VueApp implements Stringable $data['stores'] = $this->stores; } + if (count($this->plugins) > 0) { + $data['plugins'] = $this->plugins; + } + $template = $GLOBALS['template_factory']->open('vue-app.php'); $template->baseComponent = basename($this->base_component); $template->attributes = ['data-vue-app' => json_encode($data)]; diff --git a/resources/assets/javascripts/bootstrap/stock-images.js b/resources/assets/javascripts/bootstrap/stock-images.js deleted file mode 100644 index 6ed6edff485fb8e332889c583a82f34938e65607..0000000000000000000000000000000000000000 --- a/resources/assets/javascripts/bootstrap/stock-images.js +++ /dev/null @@ -1,5 +0,0 @@ -import StockImages from '../lib/stock-images.js'; - -STUDIP.domReady(() => { - StockImages.init(); -}); diff --git a/resources/assets/javascripts/bootstrap/vue.js b/resources/assets/javascripts/bootstrap/vue.js index ce1aa0d5eea8c9c5f1b2d9569a90948c71fe8390..551dacaa0735208df52f1eb767d8d82d8ef5dbff 100644 --- a/resources/assets/javascripts/bootstrap/vue.js +++ b/resources/assets/javascripts/bootstrap/vue.js @@ -3,6 +3,7 @@ STUDIP.ready(() => { const config = Object.assign( { components: [], + plugins: {}, stores: {} }, JSON.parse(node.dataset.vueApp) @@ -37,7 +38,7 @@ STUDIP.ready(() => { }; }); - STUDIP.Vue.load().then(async ({createApp, store}) => { + STUDIP.Vue.load().then(async ({createApp, store, Vue}) => { for (const [index, name] of Object.entries(config.stores)) { import(`../../../vue/store/${name}.js`).then(storeConfig => { store.registerModule(index, storeConfig.default); @@ -53,6 +54,13 @@ STUDIP.ready(() => { } }); } + + for (const [plugin, filename] of Object.entries(config.plugins)) { + import(`../../../vue/plugins/${filename}.js`) + .then((temp) => Vue.use(temp[plugin], { store })); + } + + createApp({ components, store, diff --git a/resources/assets/javascripts/entry-base.js b/resources/assets/javascripts/entry-base.js index 3c2223e025538534253ec86487bcee78d0b5d14e..7a382b8cd6ee64be4d3899dc6ce48129b03b14e9 100644 --- a/resources/assets/javascripts/entry-base.js +++ b/resources/assets/javascripts/entry-base.js @@ -77,7 +77,6 @@ import "./bootstrap/scroll_to_top.js" import "./bootstrap/admin-courses.js" import "./bootstrap/oer.js" import "./bootstrap/courseware.js" -import "./bootstrap/stock-images.js" import "./bootstrap/external_pages.js" import "./mvv_course_wizard.js" diff --git a/resources/assets/javascripts/lib/stock-images.js b/resources/assets/javascripts/lib/stock-images.js deleted file mode 100644 index 330fbc9018598046b43390b7bea2d10a3f9faceb..0000000000000000000000000000000000000000 --- a/resources/assets/javascripts/lib/stock-images.js +++ /dev/null @@ -1,23 +0,0 @@ -const StockImages = { - init() { - const stockImagesPage = document.querySelector('div.stock-images'); - if (stockImagesPage !== null) { - Promise.all([window.STUDIP.Vue.load(), StockImages.plugin()]).then( - ([{ Vue, createApp, store }, StockImagesPlugin]) => { - Vue.use(StockImagesPlugin, { store }); - createApp({ - el: stockImagesPage, - render: (h) => { - return h(Vue.component('StockImagesPage'), { props: {} }); - }, - }); - } - ); - } - }, - plugin() { - return import('@/vue/plugins/stock-images.js').then(({ StockImagesPlugin }) => StockImagesPlugin); - }, -}; - -export default StockImages; diff --git a/resources/vue/components/stock-images/ImagesPagination.vue b/resources/vue/components/stock-images/ImagesPagination.vue index 2cd1621a9e1f02dbacd4941b0fc1736e6ae20d52..16dd96ab0a7728ea983fc3f7ed0c80267daf852b 100644 --- a/resources/vue/components/stock-images/ImagesPagination.vue +++ b/resources/vue/components/stock-images/ImagesPagination.vue @@ -1,7 +1,7 @@ <template> <div> <StudipPagination - :style="{ visibility: totalItems <= perPage ? 'hidden' : 'visible' }" + v-show="totalItems > perPage" :currentOffset="offset" :totalItems="totalItems" :itemsPerPage="perPage" @@ -9,7 +9,7 @@ /> <slot></slot> <StudipPagination - :style="{ visibility: totalItems <= perPage ? 'hidden' : 'visible' }" + v-show="totalItems > perPage" :currentOffset="offset" :totalItems="totalItems" :itemsPerPage="perPage" diff --git a/resources/vue/components/stock-images/SearchWidget.vue b/resources/vue/components/stock-images/SearchWidget.vue index 2288c66bfcbe657da787132bd600e75e8ec081c3..75ba7847680b7866a16a9de29507f15fcf10a802 100644 --- a/resources/vue/components/stock-images/SearchWidget.vue +++ b/resources/vue/components/stock-images/SearchWidget.vue @@ -14,7 +14,7 @@ <button v-if="showSearchResults" @click.prevent="onReset" - class="reset-search" + class="reset-search as-link" :title="$gettext('Suchformular zurücksetzen')" > <studip-icon shape="decline" :size="20" role="presentation" alt="" />