feat: implement usage tracker + quotas

This commit is contained in:
Ruben Fiszel
2022-12-11 18:47:39 +01:00
parent 7bc0c2b0c4
commit 039e1fa1e6
32 changed files with 860 additions and 642 deletions
+1 -1
View File
@@ -77,7 +77,7 @@
<div class="flex flex-row justify-between">The next runs will be scheduled at:</div>
<ul class="list-disc mx-12">
{#each preview.slice(0, limit) as p}
<li class="mx-2 text-gray-700 text-sm">{displayDate(p)}</li>
<li class="mx-2 text-gray-700 text-sm">{displayDate(p, true)}</li>
{/each}
<li class="text-sm mx-2">...</li>
{#if limit != 10}
+3 -3
View File
@@ -36,7 +36,7 @@
dispatch('click', { item: item?.eventName })
}
}}
class="block whitespace-nowrap hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30 px-4 py-2 text-sm text-gray-700 text-left{item.separatorTop
class="block w-full whitespace-nowrap hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30 px-4 py-2 text-sm text-gray-700 text-left {item.separatorTop
? 'border-t'
: ''} {item.separatorBottom ? 'border-b' : ''} {item.type == 'delete'
? 'text-red-500'
@@ -64,7 +64,7 @@
close()
}
}}
class="block px-4 py-2 text-sm text-gray-700 hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30"
class="block w-full px-4 py-2 text-sm text-gray-700 hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30"
role="menuitem"
tabindex="-1"
id="user-menu-item-{name}-{i}}"
@@ -81,7 +81,7 @@
</a>
{:else}
<span
class="block px-4 py-2 text-sm text-gray-700"
class="block px-4 py-2 text-sm text-gray-700"
role="menuitem"
tabindex="-1"
id="user-menu-item-{name}-{i}}"
@@ -28,13 +28,13 @@
fill: #ffffff;
}
.st2 {
fill: #999;
fill: #bcd4fc;
}
.st3 {
fill: black;
fill: #3b82f6;
}
.st4 {
fill: #999;
fill: #b3b3b3;
}
.st5 {
fill: url(#SVGID_1_);
+1
View File
@@ -8,6 +8,7 @@ export interface UserExt {
email: string;
username: string;
is_admin: boolean;
is_super_admin: boolean;
created_at: string;
groups: string[];
pgroups: string[];
+2 -2
View File
@@ -4,7 +4,7 @@ import { FlowService, Script, ScriptService, type Flow, type FlowModule, type Us
import { toast } from '@zerodevx/svelte-toast'
import { get } from 'svelte/store'
import type { Schema, SupportedLanguage } from './common'
import { hubScripts, superadmin, workspaceStore, type UserExt } from './stores'
import { hubScripts, workspaceStore, type UserExt } from './stores'
export function validateUsername(username: string): string {
if (username != '' && !/^\w+$/.test(username)) {
@@ -179,7 +179,7 @@ export function canWrite(
if (!user) {
return false
}
if (user.is_admin || get(superadmin)) {
if (user.is_admin || user.is_super_admin) {
return true
}
let userOwner = `u/${user.username}`
@@ -1,14 +1,13 @@
<script context="module">
export function load({ params }) {
return {
stuff: { title: `Script ${params.hash}` }
stuff: { title: `App ${params.path}` }
}
}
</script>
<script lang="ts">
import { page } from '$app/stores'
import AppEditor from '$lib/components/apps/editor/AppEditor.svelte'
import AppPreview from '$lib/components/apps/editor/AppPreview.svelte'
import CenteredPage from '$lib/components/CenteredPage.svelte'
+34 -4
View File
@@ -17,6 +17,7 @@
import ShareModal from '$lib/components/ShareModal.svelte'
import SharedBadge from '$lib/components/SharedBadge.svelte'
import {
faCircle,
faEdit,
faPlus,
faShare,
@@ -28,6 +29,8 @@
import CenteredPage from '$lib/components/CenteredPage.svelte'
import Toggle from '$lib/components/Toggle.svelte'
import { Badge, Button, Skeleton } from '$lib/components/common'
import Popover from '$lib/components/Popover.svelte'
import { Icon } from 'svelte-awesome'
type ScheduleW = Schedule & { canWrite: boolean }
@@ -51,7 +54,7 @@
})
loadSchedules()
} catch (err) {
sendUserToast(`Cannot ` + (enabled ? 'disable' : 'enable') + ` schedule: ${err}`, true)
sendUserToast(`Cannot ` + (enabled ? 'enable' : 'disable') + ` schedule: ${err.body}`, true)
loadSchedules()
}
}
@@ -79,13 +82,14 @@
<th>Schedule</th>
<th>Script or Flow</th>
<th>schedule</th>
<th />
<th>off/on</th>
<th>timezone</th>
<th>last edit</th>
<th />
</tr>
<tbody slot="body">
{#each schedules as { path, edited_by, edited_at, schedule, offset_, enabled, script_path, is_flow, extra_perms, canWrite }}
{#each schedules as { path, error, edited_by, edited_at, schedule, offset_, enabled, script_path, is_flow, extra_perms, canWrite }}
<tr class={enabled ? '' : 'bg-gray-50'}>
<td class="max-w-sm"
><a class="break-words text-sm" href="/schedule/add?edit={path}&isFlow={is_flow}"
@@ -101,6 +105,32 @@
></div
>
</td><td><Badge color="blue">{schedule}</Badge></td>
<td>
<div class="w-10">
{#if error}
<Popover notClickable>
<span class="flex h-4 w-4">
<Icon
class="text-red-600 animate-ping absolute inline-flex "
data={faCircle}
scale={0.7}
label="Error during last job scheduling"
/>
<Icon
class="text-red-600 relative inline-flex"
data={faCircle}
scale={0.7}
label="Error during last job scheduling"
/>
</span>
<div slot="text">
The schedule disabled itself because there was an error scheduling the next
job: {error}
</div>
</Popover>
{/if}
</div></td
>
<td>
<Toggle
checked={enabled}
@@ -117,8 +147,8 @@
<td
><span class="text-2xs">By {edited_by} <br />the {displayDate(edited_at)}</span></td
>
<td
><Dropdown
<td>
<Dropdown
placement="bottom-end"
dropdownItems={[
{
@@ -72,7 +72,7 @@
sendUserToast(`Job <a href='/run/${run}?workspace=${$workspaceStore}'>${run}</a> started`)
goto('/run/' + run + '?workspace=' + $workspaceStore)
} catch (err) {
sendUserToast(`Could not create job: ${err}`, true)
sendUserToast(`Could not create job: ${err.body}`, true)
}
}
+14 -6
View File
@@ -229,12 +229,20 @@
<div class="w-10">
{#if refresh_error}
<Popover notClickable>
<Icon
class="text-red-600 animate-[pulse_5s_linear_infinite]"
data={faCircle}
scale={0.7}
label="Error during exchange of the refresh token"
/>
<span class="flex h-4 w-4">
<Icon
class="text-red-600 animate-ping absolute inline-flex "
data={faCircle}
scale={0.7}
label="Error during exchange of the refresh token"
/>
<Icon
class="text-red-600 relative inline-flex"
data={faCircle}
scale={0.7}
label="Error during exchange of the refresh token"
/>
</span>
<div slot="text">
Latest exchange of the refresh token did not succeed. Error: {refresh_error}
</div>