who needs rust anyway
9
LICENSE.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
Copyright 2022 ptrcnull
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,9 +1,11 @@
|
|||
# gitlab-jobs
|
||||
|
||||
quick and dirty app to show all jobs from gitlab account on one screen
|
||||
quick and dirty web app to show all jobs from gitlab account on one screen
|
||||
|
||||
issue tracker: https://git.ddd.rip/ptrcnull/gitlab-jobs/issues
|
||||
|
||||
try it out: https://ptrc.pl/gitlab-jobs/
|
||||
|
||||
## usage
|
||||
|
||||
~~idk figure it out~~
|
||||
|
|
76
common.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
// native functions
|
||||
// const invoke = window.__TAURI__.invoke
|
||||
// const sendNotification = window.__TAURI__.notification.sendNotification
|
||||
// const isLoggedIn = () => invoke('is_logged_in')
|
||||
// const logIn = token => invoke('log_in', { token })
|
||||
// const listRunners = () => invoke('list_runners')
|
||||
// const listJobsForRunner = id => invoke('list_jobs_for_runner', { runnerId: id })
|
||||
// const retryJob = (projectId, jobId) => invoke('retry_job', { projectId, jobId })
|
||||
|
||||
const API = 'https://gitlab.com/api/v4'
|
||||
|
||||
const jsonify = res => res.json()
|
||||
|
||||
const isLoggedIn = async () => {
|
||||
const token = localStorage.getItem('gitlab-jobs-token')
|
||||
// TODO: check stuff?
|
||||
return token != null
|
||||
}
|
||||
|
||||
const logIn = async token => {
|
||||
const res = await fetch(API + '/user', {
|
||||
headers: {
|
||||
'PRIVATE-TOKEN': token
|
||||
}
|
||||
})
|
||||
|
||||
if (res.ok) {
|
||||
localStorage.setItem('gitlab-jobs-token', token)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const headers = () => ({ headers: { 'PRIVATE-TOKEN': localStorage.getItem('gitlab-jobs-token') } })
|
||||
|
||||
const listRunners = () => fetch(API + '/runners', headers()).then(jsonify)
|
||||
const listJobsForRunner = id => fetch(API + `/runners/${id}/jobs?order_by=id`, headers()).then(jsonify)
|
||||
const retryJob = () => {}
|
||||
|
||||
const sendNotification = async ({ title, body }) => {
|
||||
if (Notification.permission !== 'granted') {
|
||||
const result = await Notification.requestPermission()
|
||||
if (result !== 'granted') {
|
||||
console.error('did not get permission :(', result)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return new Notification(title, { body })
|
||||
}
|
||||
|
||||
// shit helpers
|
||||
const $ = (...args) => {
|
||||
if (args.length === 1) return document.querySelector(args[0])
|
||||
return args[0].querySelector(args[1])
|
||||
}
|
||||
const $$ = document.querySelectorAll.bind(document)
|
||||
|
||||
function initTemplate(template, data) {
|
||||
const fragment = template.cloneNode(true)
|
||||
Object.keys(data).forEach(key => {
|
||||
const field = fragment.querySelector('.' + key)
|
||||
const value = data[key]
|
||||
if (typeof value === 'string') {
|
||||
field.textContent = value
|
||||
} else if (typeof value === 'number') {
|
||||
field.textContent = value.toString()
|
||||
} else if (value.link) {
|
||||
const a = field.querySelector('a')
|
||||
a.href = value.link
|
||||
a.textContent = value.text
|
||||
}
|
||||
})
|
||||
return fragment
|
||||
}
|
32
dist/common.js
vendored
|
@ -1,32 +0,0 @@
|
|||
// native functions
|
||||
const invoke = window.__TAURI__.invoke
|
||||
const isLoggedIn = () => invoke('is_logged_in')
|
||||
const logIn = token => invoke('log_in', { token })
|
||||
const listRunners = () => invoke('list_runners')
|
||||
const listJobsForRunner = id => invoke('list_jobs_for_runner', { runnerId: id })
|
||||
const retryJob = (projectId, jobId) => invoke('retry_job', { projectId, jobId })
|
||||
|
||||
// shit helpers
|
||||
const $ = (...args) => {
|
||||
if (args.length === 1) return document.querySelector(args[0])
|
||||
return args[0].querySelector(args[1])
|
||||
}
|
||||
const $$ = document.querySelectorAll.bind(document)
|
||||
|
||||
function initTemplate(template, data) {
|
||||
const fragment = template.cloneNode(true)
|
||||
Object.keys(data).forEach(key => {
|
||||
const field = fragment.querySelector('.' + key)
|
||||
const value = data[key]
|
||||
if (typeof value === 'string') {
|
||||
field.textContent = value
|
||||
} else if (typeof value === 'number') {
|
||||
field.textContent = value.toString()
|
||||
} else if (value.link) {
|
||||
const a = field.querySelector('a')
|
||||
a.href = value.link
|
||||
a.textContent = value.text
|
||||
}
|
||||
})
|
||||
return fragment
|
||||
}
|
310
package-lock.json
generated
|
@ -1,310 +0,0 @@
|
|||
{
|
||||
"name": "gitlab-jobs-tauri",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "gitlab-jobs-tauri",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/api": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.0.1.tgz",
|
||||
"integrity": "sha512-TJwKkXxtF52kN9Auu5TWD2AE4ssqTrsfdpIrixYwRb3gQ/FuYwvZjrMc9weYpgsW2cMhVNkvKgneNXF/4n04lw==",
|
||||
"dependencies": {
|
||||
"type-fest": "2.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.22.0",
|
||||
"npm": ">= 6.6.0",
|
||||
"yarn": ">= 1.19.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/tauri"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.0.0.tgz",
|
||||
"integrity": "sha512-4eHnk3p0xnCXd9Zel3kLvdiiSURnN98GMFvWUAdirm5AjyOjcx8TIET/jqRYmYKE5yd+LMQqYMUfHRwA6JJUkg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tauri": "tauri.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/tauri"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tauri-apps/cli-darwin-arm64": "1.0.0",
|
||||
"@tauri-apps/cli-darwin-x64": "1.0.0",
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": "1.0.0",
|
||||
"@tauri-apps/cli-linux-arm64-gnu": "1.0.0",
|
||||
"@tauri-apps/cli-linux-arm64-musl": "1.0.0",
|
||||
"@tauri-apps/cli-linux-x64-gnu": "1.0.0",
|
||||
"@tauri-apps/cli-linux-x64-musl": "1.0.0",
|
||||
"@tauri-apps/cli-win32-ia32-msvc": "1.0.0",
|
||||
"@tauri-apps/cli-win32-x64-msvc": "1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-darwin-arm64": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.0.0.tgz",
|
||||
"integrity": "sha512-0ryomgLjdpylXypMPVXLU3PZCde3Sw5nwN4coUhBcHPBLFRb8QPet+nweVK/HiZ3mxg8WeIazvpx2s8hS0l2GQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-darwin-x64": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.0.0.tgz",
|
||||
"integrity": "sha512-oejvYUT4dEfzBi+FWMj+CMz4cZ6C2gEFHrUtKVLdTXr8Flj5UTwdB1YPGQjiOqk73LOI7cB/vXxb9DZT+Lrxgg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.0.0.tgz",
|
||||
"integrity": "sha512-yAu78v8TeXNx/ETS5F2G2Uw/HX+LQvZkX94zNiqFsAj7snfWI/IqSUM52OBrdh/D0EC9NCdjUJ7Vuo32uxf7tg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.0.0.tgz",
|
||||
"integrity": "sha512-YFUN/S58AN317njAynzcQ+EHhRsCDXqmp5g9Oiqmcdg1vU7fPWZivVLc1WHz+0037C7JnsX5PtKpNYewP/+Oqw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.0.0.tgz",
|
||||
"integrity": "sha512-al+TxMGoNVikEvRQfMyYE/mdjUcUNMo5brkCIAb+fL4rWQlAhAnYVzmg/rM8N4nhdXm1MOaYAagQmxr8898dNA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.0.0.tgz",
|
||||
"integrity": "sha512-KQmYlYyGpn6/2kSl9QivWG6EIepm6PJd57e6IKmYwAyNhLr2XfGl1CLuocUQQgO+jprjT70HXp+MXD0tcB0+Sw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-x64-musl": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.0.0.tgz",
|
||||
"integrity": "sha512-Qpaq5lZz569Aea6jfrRchgfEJaOrfLpCRBATcF8CJFFwVKmfCUcoV+MxbCIW30Zqw5Y06njC/ffa3261AV/ZIQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.0.0.tgz",
|
||||
"integrity": "sha512-e2DzFqEMI+s+gv14UupdI91gPxTbUJTbbfQlTHdQlOsTk4HEZTsh+ibAYBcCLAaMRW38NEsFlAUe1lQA0iRu/w==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.0.0.tgz",
|
||||
"integrity": "sha512-lWSs90pJeQX+L31IqIzmRhwLayEeyTh7mga0AxX8G868hvdLtcXCQA/rKoFtGdVLuHAx4+M+CBF5SMYb76xGYA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/type-fest": {
|
||||
"version": "2.13.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.13.1.tgz",
|
||||
"integrity": "sha512-hXYyrPFwETT2swFLHeoKtJrvSF/ftG/sA15/8nGaLuaDGfVAaq8DYFpu4yOyV4tzp082WqnTEoMsm3flKMI2FQ==",
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.0.1.tgz",
|
||||
"integrity": "sha512-TJwKkXxtF52kN9Auu5TWD2AE4ssqTrsfdpIrixYwRb3gQ/FuYwvZjrMc9weYpgsW2cMhVNkvKgneNXF/4n04lw==",
|
||||
"requires": {
|
||||
"type-fest": "2.13.1"
|
||||
}
|
||||
},
|
||||
"@tauri-apps/cli": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.0.0.tgz",
|
||||
"integrity": "sha512-4eHnk3p0xnCXd9Zel3kLvdiiSURnN98GMFvWUAdirm5AjyOjcx8TIET/jqRYmYKE5yd+LMQqYMUfHRwA6JJUkg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@tauri-apps/cli-darwin-arm64": "1.0.0",
|
||||
"@tauri-apps/cli-darwin-x64": "1.0.0",
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": "1.0.0",
|
||||
"@tauri-apps/cli-linux-arm64-gnu": "1.0.0",
|
||||
"@tauri-apps/cli-linux-arm64-musl": "1.0.0",
|
||||
"@tauri-apps/cli-linux-x64-gnu": "1.0.0",
|
||||
"@tauri-apps/cli-linux-x64-musl": "1.0.0",
|
||||
"@tauri-apps/cli-win32-ia32-msvc": "1.0.0",
|
||||
"@tauri-apps/cli-win32-x64-msvc": "1.0.0"
|
||||
}
|
||||
},
|
||||
"@tauri-apps/cli-darwin-arm64": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.0.0.tgz",
|
||||
"integrity": "sha512-0ryomgLjdpylXypMPVXLU3PZCde3Sw5nwN4coUhBcHPBLFRb8QPet+nweVK/HiZ3mxg8WeIazvpx2s8hS0l2GQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@tauri-apps/cli-darwin-x64": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.0.0.tgz",
|
||||
"integrity": "sha512-oejvYUT4dEfzBi+FWMj+CMz4cZ6C2gEFHrUtKVLdTXr8Flj5UTwdB1YPGQjiOqk73LOI7cB/vXxb9DZT+Lrxgg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.0.0.tgz",
|
||||
"integrity": "sha512-yAu78v8TeXNx/ETS5F2G2Uw/HX+LQvZkX94zNiqFsAj7snfWI/IqSUM52OBrdh/D0EC9NCdjUJ7Vuo32uxf7tg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@tauri-apps/cli-linux-arm64-gnu": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.0.0.tgz",
|
||||
"integrity": "sha512-YFUN/S58AN317njAynzcQ+EHhRsCDXqmp5g9Oiqmcdg1vU7fPWZivVLc1WHz+0037C7JnsX5PtKpNYewP/+Oqw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@tauri-apps/cli-linux-arm64-musl": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.0.0.tgz",
|
||||
"integrity": "sha512-al+TxMGoNVikEvRQfMyYE/mdjUcUNMo5brkCIAb+fL4rWQlAhAnYVzmg/rM8N4nhdXm1MOaYAagQmxr8898dNA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@tauri-apps/cli-linux-x64-gnu": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.0.0.tgz",
|
||||
"integrity": "sha512-KQmYlYyGpn6/2kSl9QivWG6EIepm6PJd57e6IKmYwAyNhLr2XfGl1CLuocUQQgO+jprjT70HXp+MXD0tcB0+Sw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@tauri-apps/cli-linux-x64-musl": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.0.0.tgz",
|
||||
"integrity": "sha512-Qpaq5lZz569Aea6jfrRchgfEJaOrfLpCRBATcF8CJFFwVKmfCUcoV+MxbCIW30Zqw5Y06njC/ffa3261AV/ZIQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@tauri-apps/cli-win32-ia32-msvc": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.0.0.tgz",
|
||||
"integrity": "sha512-e2DzFqEMI+s+gv14UupdI91gPxTbUJTbbfQlTHdQlOsTk4HEZTsh+ibAYBcCLAaMRW38NEsFlAUe1lQA0iRu/w==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@tauri-apps/cli-win32-x64-msvc": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.0.0.tgz",
|
||||
"integrity": "sha512-lWSs90pJeQX+L31IqIzmRhwLayEeyTh7mga0AxX8G868hvdLtcXCQA/rKoFtGdVLuHAx4+M+CBF5SMYb76xGYA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"type-fest": {
|
||||
"version": "2.13.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.13.1.tgz",
|
||||
"integrity": "sha512-hXYyrPFwETT2swFLHeoKtJrvSF/ftG/sA15/8nGaLuaDGfVAaq8DYFpu4yOyV4tzp082WqnTEoMsm3flKMI2FQ=="
|
||||
}
|
||||
}
|
||||
}
|
12
package.json
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"name": "gitlab-jobs-tauri",
|
||||
"scripts": {
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^1.0.0"
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
table {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
display: block;
|
||||
}
|
||||
td.status {
|
||||
font-weight: bold;
|
||||
|
@ -63,11 +64,11 @@
|
|||
const template = $('.template')
|
||||
const table = $('tbody')
|
||||
|
||||
let notifications = true
|
||||
let notifications = false
|
||||
|
||||
$('th.status').addEventListener('click', ev => {
|
||||
notifications = !notifications
|
||||
window.__TAURI__.notification.sendNotification({
|
||||
sendNotification({
|
||||
title: 'GitLab Jobs',
|
||||
body: `Notifications are now ${notifications ? 'enabled' : 'disabled'}`
|
||||
})
|
||||
|
@ -93,7 +94,7 @@
|
|||
existing.className = ''
|
||||
existing.classList.add(job.status)
|
||||
if (['success', 'failed'].includes(job.status)) {
|
||||
window.__TAURI__.notification.sendNotification({
|
||||
sendNotification({
|
||||
title: 'GitLab Jobs',
|
||||
body: `Job ${job.name} for ${job.project.name}: ${job.status}`
|
||||
})
|
||||
|
@ -154,4 +155,4 @@
|
|||
setInterval(updateJobs, 5000)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
3
src-tauri/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
4270
src-tauri/Cargo.lock
generated
|
@ -1,30 +0,0 @@
|
|||
[package]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
description = "A Tauri App"
|
||||
authors = ["ptrcnull"]
|
||||
license = ""
|
||||
repository = ""
|
||||
default-run = "app"
|
||||
edition = "2021"
|
||||
rust-version = "1.57"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "1.0.0", features = [] }
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
tauri = { version = "1.0.0", features = ["api-all"] }
|
||||
gitlab = "0.1500.0"
|
||||
chrono = { version = "0.4", default-features = false, features = ["clock", "serde"] }
|
||||
|
||||
[features]
|
||||
# by default Tauri runs in production mode
|
||||
# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
|
||||
default = [ "custom-protocol" ]
|
||||
# this feature is used used for production builds where `devPath` points to the filesystem
|
||||
# DO NOT remove this
|
||||
custom-protocol = [ "tauri/custom-protocol" ]
|
|
@ -1,3 +0,0 @@
|
|||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 974 B |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 903 B |
Before Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 14 KiB |
|
@ -1,77 +0,0 @@
|
|||
// additional queries not defined in the gitlab crate
|
||||
|
||||
use gitlab::{api::{endpoint_prelude::Method, Endpoint}, *};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
pub struct RunnerJobs {
|
||||
pub runner_id: String,
|
||||
}
|
||||
|
||||
impl Endpoint for RunnerJobs {
|
||||
fn method(&self) -> Method {
|
||||
Method::GET
|
||||
}
|
||||
|
||||
fn endpoint(&self) -> std::borrow::Cow<'static, str> {
|
||||
format!("runners/{}/jobs?order_by=id", self.runner_id).into()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Runners {}
|
||||
impl Endpoint for Runners {
|
||||
fn method(&self) -> Method {
|
||||
Method::GET
|
||||
}
|
||||
|
||||
fn endpoint(&self) -> std::borrow::Cow<'static, str> {
|
||||
"runners".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Job {
|
||||
/// The ID of the job.
|
||||
pub id: JobId,
|
||||
/// The status of the job.
|
||||
pub status: StatusState,
|
||||
pub stage: String,
|
||||
/// The name of the job.
|
||||
pub name: String,
|
||||
#[serde(rename = "ref")]
|
||||
/// The name of the reference that was tested.
|
||||
pub ref_: Option<String>,
|
||||
pub tag: bool,
|
||||
pub coverage: Option<f64>,
|
||||
/// When the job was created or marked as pending.
|
||||
pub created_at: DateTime<Utc>,
|
||||
/// When the job was started.
|
||||
pub started_at: Option<DateTime<Utc>>,
|
||||
/// When the job completed.
|
||||
pub finished_at: Option<DateTime<Utc>>,
|
||||
/// The user which ran the job.
|
||||
pub user: Option<User>,
|
||||
/// The artifact file uploaded from the job.
|
||||
pub artifacts_file: Option<JobArtifactFile>,
|
||||
/// The commit the job tested.
|
||||
pub commit: RepoCommit,
|
||||
/// The runner which ran the job.
|
||||
pub runner: Option<Runner>,
|
||||
/// The pipeline the job belongs to.
|
||||
pub pipeline: PipelineBasic,
|
||||
pub allow_failure: bool,
|
||||
pub duration: Option<f64>,
|
||||
pub artifacts: Option<Vec<JobArtifact>>,
|
||||
pub artifacts_expire_at: Option<DateTime<Utc>>,
|
||||
pub web_url: String,
|
||||
pub project: ProjectInfo,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ProjectInfo {
|
||||
pub id: ProjectId,
|
||||
pub name: String,
|
||||
pub name_with_namespace: String,
|
||||
pub path: String,
|
||||
pub path_with_namespace: String,
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
#![cfg_attr(
|
||||
all(not(debug_assertions), target_os = "windows"),
|
||||
windows_subsystem = "windows"
|
||||
)]
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
||||
use gitlab::{api::{AsyncQuery, projects::jobs::RetryJob}, Runner, AsyncGitlab};
|
||||
use gitlab_api::Job;
|
||||
|
||||
pub mod gitlab_api;
|
||||
|
||||
struct AppState {
|
||||
gl: Option<AsyncGitlab>
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
gl: None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_client(&self) -> Result<AsyncGitlab, String> {
|
||||
match &self.gl {
|
||||
Some(client) => Ok(client.clone()),
|
||||
None => {
|
||||
Err("not logged in".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type State<'a> = tauri::State<'a, Mutex<AppState>>;
|
||||
|
||||
#[tauri::command]
|
||||
fn is_logged_in(state: State) -> bool {
|
||||
state.lock().unwrap().gl.is_some()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn log_in(token: String, state: State<'_>) -> Result<(), String> {
|
||||
let gitlab_client = gitlab::GitlabBuilder::new("gitlab.com", token).build_async().await;
|
||||
match gitlab_client {
|
||||
Ok(client) => {
|
||||
state.lock().unwrap().gl.replace(client);
|
||||
Ok(())
|
||||
},
|
||||
Err(error) => Err(error.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn list_runners(state: State<'_>) -> Result<Vec<Runner>, String> {
|
||||
let client = {
|
||||
let appstate = state.lock().unwrap();
|
||||
appstate.get_client()
|
||||
}?;
|
||||
|
||||
let endpoint = gitlab_api::Runners{};
|
||||
let response: Result<Vec<Runner>, _> = endpoint.query_async(&client).await;
|
||||
response.map_err(|err| err.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn list_jobs_for_runner(runner_id: String, state: State<'_>) -> Result<Vec<Job>, String> {
|
||||
let client = {
|
||||
let appstate = state.lock().unwrap();
|
||||
appstate.get_client()
|
||||
}?;
|
||||
|
||||
let endpoint = gitlab_api::RunnerJobs{runner_id};
|
||||
let response: Result<Vec<Job>, _> = endpoint.query_async(&client).await;
|
||||
response.map_err(|err| err.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn retry_job(project_id: String, job_id: u64, state: State<'_>) -> Result<Job, String> {
|
||||
let client = {
|
||||
let appstate = state.lock().unwrap();
|
||||
appstate.get_client()
|
||||
}?;
|
||||
|
||||
let endpoint = RetryJob::builder().project(project_id).job(job_id).build().unwrap();
|
||||
let response: Result<Job, _> = endpoint.query_async(&client).await;
|
||||
response.map_err(|err| err.to_string())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let context = tauri::generate_context!();
|
||||
tauri::Builder::default()
|
||||
.manage(Mutex::new(AppState::default()))
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
is_logged_in,
|
||||
log_in,
|
||||
list_runners,
|
||||
list_jobs_for_runner,
|
||||
retry_job
|
||||
])
|
||||
.menu(tauri::Menu::os_default(&context.package_info().name))
|
||||
.run(context)
|
||||
.expect("error while running tauri application");
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"build": {
|
||||
"beforeBuildCommand": "",
|
||||
"beforeDevCommand": "",
|
||||
"devPath": "../dist",
|
||||
"distDir": "../dist",
|
||||
"withGlobalTauri": true
|
||||
},
|
||||
"package": {
|
||||
"productName": "gitlab-jobs",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
"all": true
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"category": "DeveloperTool",
|
||||
"copyright": "",
|
||||
"deb": {
|
||||
"depends": []
|
||||
},
|
||||
"externalBin": [],
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"identifier": "me.ptrcnull.gitlab-jobs",
|
||||
"longDescription": "",
|
||||
"macOS": {
|
||||
"entitlements": null,
|
||||
"exceptionDomain": "",
|
||||
"frameworks": [],
|
||||
"providerShortName": null,
|
||||
"signingIdentity": null
|
||||
},
|
||||
"resources": [],
|
||||
"shortDescription": "",
|
||||
"targets": "all",
|
||||
"windows": {
|
||||
"certificateThumbprint": null,
|
||||
"digestAlgorithm": "sha256",
|
||||
"timestampUrl": ""
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"csp": null
|
||||
},
|
||||
"updater": {
|
||||
"active": false
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"fullscreen": false,
|
||||
"height": 600,
|
||||
"resizable": true,
|
||||
"title": "GitLab Jobs",
|
||||
"width": 800
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ body {
|
|||
height: 100%;
|
||||
background-color: #1f1f1f;
|
||||
color: #ffffff;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
body {
|