Skip to content

Preparation for Shlink Dashboard #338

@acelaya

Description

@acelaya

Shlink web client is a fully static web app, with no backend.

That's pretty convenient, and simplifies a lot of things, but also introduces some limitations.

  • Servers and configuration is not shared, which means every time you open the app in a new device, you need to configure it from scratch.
  • Everything is public, so you cannot set permissions or user authentication.
  • Shlink API keys are stored in the browser, which is a bit risky if someone else can access your computer.
  • Many people don't understand the difference of a web app with backend and without it, which makes them not understand why the former points are not possible.

Since there has been requests for this in the past, I'm considering a new shlink-dashboard project, which would be a web client but with its own backend for frontend.

In order to do it, we need to split shlink-web-client, having a subcomponent which wraps all the operations done when you are connected to a server.

This component would be reused by both shlink-web-client and shlink-dashboard, and the list of servers, configs, etc, would be handled differently by each one of them.

It should aslo allow (at some point) to provide the list of permissions, so that shlink-dashboard can "hide" sections based on the user's permissions.

Once the component has been split (shlink-web-component?), it can be moved to its own repo and published separately as an npm package.


TODO

  • Split redux store
    • APP:
      • appUpdates
      • servers (remoteServers, selectedServer)
      • settings
      • sidebar
    • COMPONENT:
      • Everything else
  • Split container definition
  • Identify common components between this component and the wrapping app
    • Result
    • Message
    • SimpleCard
    • SearchField
    • DropdownBtn
    • RowDropdownBtn
    • InputFormGroup
    • Checkbox, ToggleSwitch and BooleanControl
    • NavPills and NavPillItem
    • OrderingDropdown and order helpers.
    • hooks:
      • useDomId
      • useElementRef
      • useToggle
  • Define the API client contract
  • Think how to use mercure:
    • Let component subscribe.
    • Pass updates from app
  • Define what/how to export from component package
  • Make sure shlink-web-component does not have dependencies on the app
  • Consider how to split/bundle stylesheets
    • Compile pure styles and distribute an index.css file. Import them once.
    @import '@shlinkio/shlink-frontend-kit/index';
    @import '@shlinkio/shlink-web-component/index';
    • Expose mixins and vars on a base.scss which is distributed uncompiled and then imported wherever needed.
    @import '@shlinkio/shlink-frontend-kit/base';  
  • Extract individual stylesheets which are used only by shlink-web-component
  • Try to get rid of sidebar reducer.
  • Move short-urls/data into api-contract
  • Dynamically wrap on a Router instance if not already wrapped.
  • Review where styles are defined, and move them to the right stylesheet if needed.

Extracted component

Potential component names:

  • <Shlink />
  • <ShlinkWebComponent />
  • <ShlinkWeb />
  • <ShlinkClient />
  • <ShlinkApp />

Usage:

import { ShlinkWebComponent } from '@shlinkio/shlink-web-component';
import type { Settings } from '@shlinkio/shlink-web-component';
import type { ShlinkApiClient } from '@shlinkio/shlink-web-component/api-contract';

<ShlinkWebComponent
  settings={{} as Settings} // The settings (from local storage or server)
  serverVersion="3.7.0" // To resolve supported features.
  apiClient={{} as ShlinkApiClient} // An API client / an object fulfilling a contract. Implicitly knows how to consume current server

  // Object determining the active section and its params, or use react-router?
  activeSection={{}}

  // Future versions
  permissions={{}} // Allows to hide sections or restrict actions
/>

Peer dependencies:

  • @reduxjs/toolkit (redux?)
  • react-redux
  • react
  • react-dom
  • bootstrap
  • reactstrap
  • date-fns

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions