Superset如何快速建立看板CSS模板

在superset0.3.6的看板,在新增和編輯時,是能夠直接添加css樣式去控制整個看板頁面任意元素的樣式。或者在管理菜單--css模板添加相應css模板,而後編輯看板時直接選擇應用css模板。
這個功能確實是香,這能夠實現不用修改一句源代碼就將看板的風格、樣式徹底改變,好比以下這樣:
Superset CSS模板效果css

但說實話,直接在看板的樣式編輯彈窗裏寫樣式,實在是太痛苦了,或者說這**徹底接受不了呀!
痛點以下:html

  • 實時預覽效果太差--須要先保存,而後試下效果,而後繼續編輯看板,選擇編輯CSS模板,再接着寫,如此往復;
  • 沒有代碼提示;
  • 不能夠使用css預處理語言;

這是簡單分享,我是使用使用gulp+electron解決這些問題的。node

項目初始化

mkdir theme_editor
cd theme_editor
npm init -y

使用electron加載頁面注入css

安裝electron,下載electron會須要一點時間,可嘗試使用cnpmgit

npm install electron -D

根目錄下添加main.jsweb

const { app, BrowserWindow } = require('electron')

// 建立electron window 
function createWindow () {
  const win = new BrowserWindow({
    webPreferences: {
      // 開啓開發工具,方便調試
      devTools: true
    }
  })
  // superset web服務地址
  // 建議使用生產地址,本地就能夠不須要啓動superset後端服務了
  const url = 'http://127.0.0.1:5000'
  // 這個是要插入css樣式文件的頁面路徑
  // 並不須要全部頁面都插入css樣式
  // 全部的看板頁面都插入css樣式
  const insertCssPath = new RegExp('/superset/dashboard/')
  // 若是是在本地superset的服務
  // 可直接把css文件放在superset項目的superset/static/assets目錄下,而後以下使用
  // 若是是加載的生產地址,則可以使用IIS或者Nginx搭建一個本地web服務,返回css文件
  // 直接如:http://localhost:8080/style/theme.css,使用
  const cssUrl = '/static/assets/theme.css'

  // 加載頁面
  win.loadURL(url)

  // 監聽頁面準備完成,插入樣式
  win.webContents.on('dom-ready', () => {
    let webUrl = win.webContents.getURL()
    
    if (insertCssPath.test(webUrl)) {
      // 若是是須要插入樣式文件
      // 執行js代碼往當前頁面插入樣式文件
      win.webContents.executeJavaScript(`
        const link = document.createElement('link');
        link.setAttribute('type','text/css');
        link.setAttribute('rel','stylesheet');
        link.setAttribute('href','${cssUrl}');
        document.head.appendChild(link);`
      )

      return false
    }

  })

}

app.whenReady().then(createWindow)

package.json添加一個腳本,修改main屬性:npm

{
  "name": "theme_editor",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "electron ."
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "electron": "^10.1.2"
  }
}

在superset項目,superset/static/assets目錄下添加theme.cssjson

#app {
  height: 100%;
  overflow: hidden;
  background: linear-gradient(180deg, #3F4685 0%, #222648 100%);
}

而後,跑起superset先後端服務。當前目錄執行命令gulp

npm run start

若是一切正常,上面命令會彈出一個electron窗口,加載superset的web服務,登錄後打開任意一個看板,看板的背景會變成theme文件設置成的顏色,以下:
修改background後端

這裏有幾個須要強調注意的地方:緩存

  1. loadURL的URL請根據實際狀況配置(本地也可能並不是5000端口),建議使用線上服務;
  2. 關於css文件的路徑,使用superset纔可直接放在superset/static目錄下,如何使用線上地址,須要在本地搭建web服務來訪問css文件地址;
  3. 若是使用superset服務加載css文件,會有緩存,須要在開發者工具的network中禁用緩存(Disable cache);
  4. electron窗口中使用;

以上,咱們就實現瞭如何使用electron實現能夠在本身喜歡的編輯器中,編輯樣式了。但仍是有如下問題:

  1. 雖然預覽比以前好了,但每次修改後仍是要ctrl+r去刷新,沒有作到自動刷新。
  2. 若是我想使用CSS預編譯語言呢?

接下來,用gulp解決上面兩個問題。

使用gulp結合electron-connect實現自動刷新

安裝相關依賴:

npm install gulp gulp-cli electron-connect -D

添加gulpfile.js:

const { watch, task } = require('gulp');
const elecConnect = require('electron-connect').server.create(); 

// 樣式修改使用electron-connect刷新,electron窗體
function reload (cb) {
  elecConnect.reload()
  cb()
}

task('watch', function () {
  elecConnect.start()
  watch(['./theme.css'], reload)
})

同時,在main.js中使用connect:

// 修改main.js,在第二行引入connect
const client = require('electron-connect').client
...
// 在win.loadURL(url)後添加
client.create(win)

在當前目標下添加theme.css,起個IIS服務指向theme_editor,**我這裏端口是88,因此須要把main.jscssUrl值修改成http://localhost:88/theme.css

// main.js
...
const cssUrl = 'http://localhost:88/theme.css'
...

最後,當前目錄執行命令:

npx gulp watch

若是這裏沒出問題,那麼,你修改theme.css後,electron-connect就會自動把electron窗口當前的頁面刷新一下。這裏我碰到一個問題,提示electron不存在,刪除node_modules再從新install一次解決。這裏還有一點要注意下,若是npm版本小於5.2,是沒法使用npx,要麼升級node版本,要麼全局安裝gulp-cli而後直接跑gulp watch
好了,到目前爲止,咱們又解決了一個自動刷新的需求。下面,咱們來實現一下預處理。

使用gulp-less實現預處理

安裝gulp-less,若是想使用其它css預編譯語言,能夠安裝相關的gulp插件

npm install gulp-less -D

修改gulpfile.js

const { watch, task, dest, src, series } = require('gulp')
const elecConnect = require('electron-connect').server.create() 
const less = require('gulp-less')


// 樣式修改使用electron-connect刷新,electron窗體
function reload (cb) {
  elecConnect.reload()
  cb()
}

// 編譯less
function lessCompier () {
  return src('./*.less')
  .pipe(less())
  .pipe(dest('./'))
}

task('watch', function () {
  elecConnect.start()
  series(lessCompier)()
  // 修改成監聽less改變
  watch(['./theme.less'], series(lessCompier, reload))
})

添加theme.less

#app{
  height: 100%;
  overflow: hidden;
  background: linear-gradient(180deg, #3F4685 0%, #222648 100%);
}

再次運行npx gulp watch,這時,只要你修改theme.less,頁面也會自動刷新了。

其它

到這裏,咱們的需求已經實在。但依然還有幾個不完美的地方,好比每次啓動electron咱們都須要從新登陸下,能夠這樣處理下:

// 在main.js的dom-ready事件的回調函數裏面
// 判斷下若是是進行了登陸頁面,自動輸入密碼並登錄
if (/\/login\/$/.test(webUrl)) {
  win.webContents.insertCSS('html, body { background-color: #f00; }')
  // 下面輸入你係統的用戶名,密碼
  win.webContents.executeJavaScript(`
    $("#username")[0].value="admin";
    $("#password")[0].value="123456";
    $("form[name=login]")[0].submit();
  `, true)
  .then(() => {
    console.log('login success')
  })
  .catch(err => {
    console.log('login Error:', err)
  })
  return false
}

若是以爲,但願每次都直接登錄,並跳轉到具體看板,咱們能夠粥在main.js的dom-ready事件的回調函數後面添加代碼:

// href填入指定url
win.webContents.executeJavaScript(`location.href="http://127.0.0.1:5000/superset/dashboard/births/"`)

以上,完整代碼: theme-editor

有時,咱們想作的可能更復雜,好比對小圖片轉base64,對於未轉base64的圖片但願能夠自動輸出到指定目錄並在css文件中作替換,壓縮css代碼,打包前先壓縮圖片等等,這些gulp都有相應的插件去實現。相應能夠看theme-editor,dev分支的gulpfile文件。

相關文章
相關標籤/搜索