From c69810bad9d1ef83d3918570b27f7b07fee89ed9 Mon Sep 17 00:00:00 2001 From: Gregor Aisch Date: Tue, 27 Apr 2021 10:50:51 +0200 Subject: [PATCH 01/53] feat: svelte navbar with plugin support --- src/server.js | 3 + src/styles/index.scss | 1 + src/utils/header-links.js | 118 ++++++++++++++++++ src/utils/svelte-view/context.js | 4 +- src/views/layout/partials/PageHeader.svelte | 34 +++-- .../layout/partials/header/NavBar.svelte | 63 +++++++++- static/datawrapper.css | 4 +- 7 files changed, 210 insertions(+), 17 deletions(-) create mode 100644 src/utils/header-links.js diff --git a/src/server.js b/src/server.js index 357526e0..61ed45b8 100644 --- a/src/server.js +++ b/src/server.js @@ -16,6 +16,7 @@ const registerVisualizations = require('@datawrapper/service-utils/registerVisua const config = requireConfig(); const path = require('path'); const { getUserLanguage } = require('./utils'); +const headerLinks = require('./utils/header-links'); const { SvelteView, getView, @@ -146,6 +147,8 @@ const start = async () => { server.method('isDevMode', () => process.env.DW_DEV_MODE); server.method('registerVisualization', registerVisualizations(server)); + await server.register(headerLinks); + // hooks server.app.event = eventList; server.app.events = new FrontendEventEmitter({ logger: server.logger, eventList }); diff --git a/src/styles/index.scss b/src/styles/index.scss index d1156137..4e975fda 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -13,6 +13,7 @@ $background: $dw_lightgray; $body-background-color: $dw_background; $light: $dw_gray; $tabs-boxed-link-active-background-color: $dw_background; +$navbar-background-color: transparent; $table-background-color: transparent; $table-striped-row-even-background-color: hsla(0,0,0, 0.03); diff --git a/src/utils/header-links.js b/src/utils/header-links.js new file mode 100644 index 00000000..aa058993 --- /dev/null +++ b/src/utils/header-links.js @@ -0,0 +1,118 @@ +const { getUserLanguage } = require('./index'); + +module.exports = { + name: 'header-links', + version: '1.0.0', + async register(server, options) { + server.app.headerLinks = new Set(); + + server.method('registerHeaderLinks', headerLinkFunc => { + server.app.headerLinks.add(headerLinkFunc); + }); + + server.method('getHeaderLinks', request => { + const links = []; + // evaluate links for each request, please use cache! + server.app.headerLinks.forEach(func => { + links.push.apply(links, func(request)); + }); + // sort links by order + return links.sort((a, b) => { + return a.order !== undefined && b.order !== undefined ? a.order - b.order : 0; + }); + }); + + const frontendConfig = server.methods.config('frontend'); + + // add some core header links + server.methods.registerHeaderLinks(request => { + const language = getUserLanguage(request.auth); + const __ = key => server.methods.translate(key, { scope: 'core' }); + return [ + { + id: 'dashboard', + fontIcon: 'fa fa-fw fa-bar-chart-o', + title: __('Dashboard'), + url: '/', + order: 5 + }, + { + id: 'create-new', + fontIcon: 'fa fa-fw fa-plus', + title: __('Create new...'), + order: 10, + submenuItems: [ + { + id: 'create-chart', + svgIcon: 'dw-chart', + title: __('New chart'), + url: '/create/chart', + order: 10 + }, + { + id: 'create-map', + svgIcon: 'dw-map', + title: __('New chart'), + url: '/select/map', + order: 20 + }, + { + id: 'create-table', + svgIcon: 'dw-table', + title: __('New chart'), + url: '/create/table', + order: 30 + } + ] + }, + { + id: 'my-charts', + fontIcon: 'fa fa-fw fa-bar-chart-o', + title: __('Archive'), + url: '/mycharts', + order: 60 + }, + { + id: 'separator', + order: 69 + }, + { + id: 'settings', + // fontIcon: 'im im-globe', + title: language.substr(0, 2).toLowerCase(), + order: 90, + submenuItems: (frontendConfig.languages || []).map(({ id, title, flag }) => ({ + id, + title: `${flag} ${title}` + })) + }, + { + id: 'settings', + fontIcon: 'fa-fw fa fa fa-bars', + order: 95, + submenuItems: [ + { + url: '/account', + title: 'Settings' + }, + { + url: '/account/teams', + title: 'My teams' + }, + { + url: '/account/teams', + title: 'Language' + }, + { + id: 'separator' + }, + { + url: '/account/teams', + title: 'Logout' + } + ] + } + ]; + }); + } +}; diff --git a/src/utils/svelte-view/context.js b/src/utils/svelte-view/context.js index 9834893b..a7ed7eae 100644 --- a/src/utils/svelte-view/context.js +++ b/src/utils/svelte-view/context.js @@ -21,7 +21,9 @@ module.exports = function (request) { frontendDomain: `${frontendConfig.domain}`, imageDomain: `${generalConfig.imageDomain}`, dev: process.env.DW_DEV_MODE, - footerLinks: frontendConfig.footerLinks || [] + footerLinks: frontendConfig.footerLinks || [], + languages: frontendConfig.languages || [], + headerLinks: server.methods.getHeaderLinks(request) }, request: { method: request.method, diff --git a/src/views/layout/partials/PageHeader.svelte b/src/views/layout/partials/PageHeader.svelte index 48ac0f47..21e5e95d 100644 --- a/src/views/layout/partials/PageHeader.svelte +++ b/src/views/layout/partials/PageHeader.svelte @@ -4,20 +4,35 @@ import NavBar from './header/NavBar.svelte'; const request = getContext('request'); + let isActive = false;
-
- {#if $request.path === '/'} - - {:else} - +
+ +
@@ -26,7 +41,4 @@ /*background: white; border-bottom: 1px solid #eee;*/ } - .container { - margin-bottom: 0; - } diff --git a/src/views/layout/partials/header/NavBar.svelte b/src/views/layout/partials/header/NavBar.svelte index df61bee5..149ceda6 100644 --- a/src/views/layout/partials/header/NavBar.svelte +++ b/src/views/layout/partials/header/NavBar.svelte @@ -1,14 +1,71 @@ - +