refactor(frontend): Tailwind refactor (#637)

* feat(frontend): Tailwind config migration
This commit is contained in:
Ádám Kovács
2022-10-03 11:27:58 +02:00
committed by GitHub
parent 5d46496342
commit 6a28b68dbf
64 changed files with 907 additions and 939 deletions
-229
View File
@@ -2,232 +2,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
html {
overflow-y: auto;
}
@layer base {
h1 {
@apply text-2xl;
@apply sm:pb-4 font-semibold;
}
h2 {
@apply text-xl;
@apply text-gray-700;
}
a {
@apply text-blue-500;
}
.flex pre code.hljs {
@apply text-sm;
}
#table-custom th {
@apply py-3.5 text-left text-sm font-semibold text-gray-900 capitalize;
}
#table-custom td {
@apply py-4 text-sm text-gray-700;
}
#table-custom tbody {
@apply divide-y divide-gray-200;
}
.dropdown {
@apply rounded-sm;
}
input[type='text'],
textarea,
select {
@apply text-sm;
}
.text-2xs {
font-size: 0.7rem;
}
.commit-hash {
@apply text-2xs;
@apply text-gray-500;
@apply bg-gray-200;
@apply font-mono;
}
.item-button {
@apply cursor-pointer;
@apply py-1;
@apply border border-gray-300;
@apply rounded-sm;
}
.item-button:hover {
@apply border border-gray-800 bg-gray-100 border-opacity-50;
}
.item-button-selected {
@apply py-1;
@apply border border-blue-500;
@apply bg-blue-50;
@apply rounded-sm;
}
.blue-button {
@apply bg-blue-500 !important;
@apply hover:bg-blue-700 !important;
}
.default-button {
/*this styling does not impact the Dropdown component */
@apply bg-blue-500;
@apply hover:bg-blue-700;
@apply text-white;
@apply font-bold;
@apply py-1 px-2;
@apply border rounded;
@apply w-min;
@apply min-w-max;
@apply text-sm;
}
.default-button-disabled {
/*this styling does not impact the Dropdown component */
@apply bg-gray-100;
@apply text-gray-300;
@apply font-bold;
@apply py-1 px-2;
@apply border rounded;
@apply w-min;
@apply min-w-max;
@apply text-sm;
}
.default-input {
@apply block;
@apply w-full;
@apply py-1;
@apply px-2;
@apply mt-1;
@apply rounded-md;
@apply border;
@apply border-gray-300;
@apply shadow-sm;
@apply text-sm;
}
.default-primary-button-v2 {
@apply text-white;
@apply bg-blue-500;
@apply border;
@apply border-blue-200;
@apply font-medium;
@apply rounded-lg;
@apply text-sm;
@apply px-5;
@apply py-2.5;
@apply text-center;
@apply inline-flex;
@apply items-center;
}
.default-primary-button-v2:focus {
@apply ring-4;
@apply outline-none;
@apply bg-blue-800;
}
.default-primary-button-v2:hover {
@apply bg-blue-800;
}
.default-secondary-button-v2 {
@apply text-gray-900;
@apply bg-white;
@apply border;
@apply border-gray-200;
@apply font-medium;
@apply rounded-lg;
@apply text-sm;
@apply px-5;
@apply py-2.5;
@apply text-center;
@apply inline-flex;
@apply items-center;
}
.default-secondary-button-v2:focus {
@apply ring-4;
@apply outline-none;
@apply ring-gray-100;
}
.default-secondary-button-v2:hover {
@apply bg-gray-100;
}
.input-error {
@apply border-red-500 !important;
}
input[disabled],
input:disabled,
textarea[disabled],
textarea:disabled {
@apply bg-gray-100 !important;
}
button:disabled,
button[disabled],
a.disabled {
/*this styling does not impact the Dropdown component */
@apply bg-gray-100 !important;
@apply text-gray-500 !important;
@apply border-none !important;
cursor: not-allowed !important;
pointer-events: none !important;
}
button:disabled svg,
button[disabled] svg,
a.disabled svg {
/*this styling does not impact the Dropdown component */
@apply text-gray-500 !important;
}
.default-button-secondary {
@apply items-center py-1 px-2;
@apply rounded bg-transparent text-blue-500 border border-blue-500 font-normal;
@apply hover:bg-transparent hover:border-blue-700 hover:text-blue-700;
@apply border rounded;
@apply w-min;
@apply min-w-max;
@apply text-sm;
}
input,
input[type='date'],
input[type='text'],
input[type='number'],
input[type='datetime-local'],
select,
textarea,
textarea[type='text'] {
@apply block;
@apply w-full py-1 px-2;
@apply border rounded-md border-gray-300;
@apply shadow-sm;
@apply focus:ring focus:ring-indigo-100 focus:ring-opacity-50;
@apply text-sm;
}
}
.inline-highlight pre code.hljs {
padding: 0;
@apply text-xs whitespace-pre-wrap;
}
/* svelte-split-pane separator class override */
.separator {
background-color: #ddd !important;
}
+85 -57
View File
@@ -31,6 +31,7 @@
import Modal from './Modal.svelte'
import Password from './Password.svelte'
import Path from './Path.svelte'
import { Button } from './common'
let manual = false
let value: string = ''
@@ -178,6 +179,10 @@
resource_type == 'gcal' ||
resource_type == 'gdrive' ||
resource_type == 'gsheets')
$: disabled =
(step == 1 && resource_type == '') ||
(step == 2 && value == '') ||
(step == 3 && pathError != '')
</script>
<Modal
@@ -207,8 +212,10 @@
<PageHeader title="OAuth APIs" />
<div class="grid sm:grid-cols-2 md:grid-cols-3 gap-x-2 gap-y-1 items-center mb-2">
{#each Object.entries(connects).sort((a, b) => a[0].localeCompare(b[0])) as [key, values]}
<button
class="px-4 h-8 {key == resource_type ? 'item-button-selected' : 'item-button'}"
<Button
variant="border"
color={key === resource_type ? 'blue' : 'dark'}
btnClasses={key === resource_type ? '!border-2 !bg-blue-50/75' : 'm-[1px]'}
on:click={() => {
manual = false
resource_type = key
@@ -219,64 +226,93 @@
}}
>
<IconedResourceType name={key} after={true} />
</button>
</Button>
{/each}
</div>
<PageHeader title="scopes" primary={false} />
<PageHeader title="Scopes" primary={false} />
{#if !manual && resource_type != ''}
{#each scopes as v}
<div class="flex flex-row max-w-md">
<div class="flex flex-row max-w-md mb-2">
<input type="text" bind:value={v} />
<button
class="default-button-secondary mx-6"
<Button
variant="border"
color="red"
size="xs"
btnClasses="mx-6"
on:click={() => {
scopes = scopes.filter((el) => el != v)
}}><Icon data={faMinus} class="mb-1" /></button
}}
>
<Icon data={faMinus} />
</Button>
</div>
{/each}
<button
class="default-button-secondary mt-1"
on:click={() => {
scopes = scopes.concat('')
}}>Add item &nbsp;<Icon data={faPlus} class="mb-1" /></button
><span class="ml-2">{(scopes ?? []).length} item{(scopes ?? []).length > 1 ? 's' : ''}</span
>
<div class="flex items-center mt-1">
<Button
variant="border"
color="blue"
size="sm"
endIcon={{ icon: faPlus }}
on:click={() => {
scopes = scopes.concat('')
}}
>
Add item
</Button>
<span class="ml-2 text-sm text-gray-500">
({(scopes ?? []).length} item{(scopes ?? []).length > 1 ? 's' : ''})
</span>
</div>
{:else}
<p class="italic text-sm">Pick an OAuth API and customize the scopes here</p>
{/if}
<PageHeader title="Extra Params" primary={false} />
{#if !manual && resource_type != ''}
{#each extra_params as [k, v]}
<div class="flex flex-row max-w-md">
<input type="text" bind:value={k} />
<div class="flex flex-row max-w-md mb-2">
<input type="text" bind:value={k} class="mr-2" />
<input type="text" bind:value={v} />
<button
class="default-button-secondary mx-6"
<Button
variant="border"
color="red"
size="xs"
btnClasses="mx-6"
on:click={() => {
extra_params = extra_params.filter((el) => el[0] != k)
}}><Icon data={faMinus} class="mb-1" /></button
}}
>
<Icon data={faMinus} />
</Button>
</div>
{/each}
<button
class="default-button-secondary mt-1"
on:click={() => {
extra_params.push(['', ''])
extra_params = extra_params
}}>Add item &nbsp;<Icon data={faPlus} class="mb-1" /></button
><span class="ml-2"
>{(extra_params ?? []).length} item{(extra_params ?? []).length > 1 ? 's' : ''}</span
>
<div class="flex items-center mt-1">
<Button
variant="border"
color="blue"
size="sm"
endIcon={{ icon: faPlus }}
on:click={() => {
extra_params.push(['', ''])
extra_params = extra_params
}}
>
Add item
</Button>
<span class="ml-2 text-sm text-gray-500">
({(extra_params ?? []).length} item{(extra_params ?? []).length > 1 ? 's' : ''})
</span>
</div>
{:else}
<p class="italic text-sm">Pick an OAuth API and customize the extra parameters here</p>
{/if}
<PageHeader title="Non OAuth APIs" />
<div class="grid sm:grid-cols-2 md:grid-cols-3 gap-x-2 gap-y-1 items-center mb-2">
{#each connectsManual as [key, instructions]}
<button
class="px-4 h-8 {key == resource_type ? 'item-button-selected' : 'item-button'}"
<Button
variant="border"
color={key === resource_type ? 'blue' : 'dark'}
btnClasses={key === resource_type ? '!border-2 !bg-blue-50/75' : 'm-[1px]'}
on:click={() => {
manual = true
resource_type = key
@@ -284,7 +320,7 @@
}}
>
<IconedResourceType name={key} after={true} />
</button>
</Button>
{/each}
</div>
{:else if step == 2}
@@ -332,32 +368,24 @@
</ul>
{/if}
</div>
<div slot="submission">
<div slot="submission" class="flex items-center gap-4">
{#if step > 1 && !no_back}
<button class="default-button px-4 py-2 font-semibold" on:click={back}>Back</button>
<Button variant="border" on:click={back}>Back</Button>
{/if}
{#if isGoogleSignin}
<button {disabled} on:click={next}>
<img class="h-10 w-auto" src="/google_signin.png" alt="Google sign-in" />
</button>
{:else}
<Button {disabled} on:click={next}>
{#if step == 1 && !manual}
Connect
{:else if step == 3}
Add resource
{:else}
Next
{/if}
</Button>
{/if}
<button
class={isGoogleSignin ? '' : 'default-button px-4 py-2 font-semibold'}
class:default-button-disabled={(step == 1 && resource_type == '') ||
(step == 2 && value == '') ||
(step == 3 && pathError != '')}
on:click={next}
>
{#if isGoogleSignin}
<img src="/google_signin.png" alt="Google sign-in" />
{:else if step == 1 && !manual}
Connect
{:else if step == 3}
Add resource
{:else}
Next
{/if}
</button>
</div>
</Modal>
<style>
.selected:hover {
@apply border border-gray-400 rounded-md border-opacity-50;
}
</style>
+14 -7
View File
@@ -4,6 +4,7 @@
import { faChevronDown, faChevronUp, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons'
import { setInputCat as computeInputCat, type InputCat } from '$lib/utils'
import { Button } from './common'
import { createEventDispatcher } from 'svelte'
import Icon from 'svelte-awesome'
import FieldHeader from './FieldHeader.svelte'
@@ -229,8 +230,11 @@
{:else}
<input type="text" bind:value={v} />
{/if}
<button
class="default-button-secondary mx-6"
<Button
variant="border"
color="red"
size="sm"
btnClasses="mx-6"
on:click={() => {
value = value.filter((el) => el != v)
if (value.length == 0) {
@@ -238,13 +242,16 @@
}
}}
>
<Icon data={faMinus} class="mb-1" />
</button>
<Icon data={faMinus} />
</Button>
</div>
{/each}
</div>
<button
class="default-button-secondary mt-1"
<Button
variant="border"
color="blue"
size="sm"
btnClasses="mt-1"
on:click={() => {
if (value == undefined) {
value = []
@@ -254,7 +261,7 @@
>
<Icon data={faPlus} class="mr-2" />
Add item
</button>
</Button>
<span class="ml-2">
{(value ?? []).length} item{(value ?? []).length > 1 ? 's' : ''}
</span>
+15 -22
View File
@@ -7,19 +7,28 @@
faShare,
faTrash
} from '@fortawesome/free-solid-svg-icons'
import { createEventDispatcher } from 'svelte'
import Icon from 'svelte-awesome'
export let category: 'delete' | 'list' | 'run' | 'add' | 'edit' | 'archive' | 'share'
export let disabled: boolean = false
const dispatch = createEventDispatcher()
const colors = {
red: 'bg-transparent hover:bg-red-600 text-red-600 font-normal hover:text-white border-red-600 hover:border-transparent rounded',
blue: 'hover:bg-blue-500 hover:text-white'
}
const getCategoryClasses = () => {
if (category === 'delete' || category === 'archive') return colors.red
else if (category === 'edit' || category === 'list' || category === 'share') return colors.blue
return ''
}
</script>
<button
class="{$$props.class} inline-flex items-center default-button py-0 px-1 {category} default-button-secondary"
on:click={() => {
dispatch('click')
}}
class="{$$props.class} inline-flex items-center bg-blue-500 hover:bg-blue-700 text-white
font-bold py-1 px-2 border rounded border-blue-500 hover:border-blue-700 w-min min-w-max
text-sm {getCategoryClasses()}"
on:click
{disabled}
>
<div class="inline-flex items-center justify-center">
@@ -56,19 +65,3 @@
{/if}
</div>
</button>
<style>
.delete,
.archive {
@apply bg-transparent hover:bg-red-600;
@apply text-red-600 font-normal hover:text-white;
@apply border-red-600 hover:border-transparent rounded;
}
.edit,
.play,
.list,
.share {
@apply hover:bg-blue-500 hover:text-white;
}
</style>
+1 -1
View File
@@ -35,7 +35,7 @@
}
</script>
<div class="text-purple-500 text-2xs grow">{cronError}</div>
<div class="text-red-600 text-2xs grow">{cronError}</div>
<div class="flex flex-row items-end max-w-5xl">
<label class="text-xs min-w-max mr-2 self-center" for="cron-schedule">CRON expression</label>
<input
+7 -5
View File
@@ -4,6 +4,7 @@
import { createEventDispatcher } from 'svelte'
import Icon from 'svelte-awesome'
import { faEllipsisH } from '@fortawesome/free-solid-svg-icons'
import { Button } from './common'
let open = false
@@ -27,15 +28,16 @@
</script>
<div
class="ml-3 {relative ? 'relative' : ''} {$$props.class}"
class="ml-2 {relative ? 'relative' : ''} {$$props.class}"
use:clickOutside
on:click_outside={handleClickOutsideMenu}
>
<button
class="text-blue-500 text-right "
id="dropdown"
<Button
color="light"
size="xs"
aria-expanded="false"
aria-haspopup="true"
btnClasses="!text-blue-500 bg-transparent"
on:click={openMenu}
>
{#if !name}
@@ -43,7 +45,7 @@
{:else}
{name}
{/if}
</button>
</Button>
<div
class="flex flex-col z-50 origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none {open
? 'visible'
@@ -442,10 +442,6 @@
})
</script>
<!-- <button class="default-button px-6 max-h-8" type="button" on:click={format}>
Format (CtrlCmd + S)
</button> -->
<div bind:this={divEl} class={$$props.class} />
<style>
+10 -8
View File
@@ -141,15 +141,16 @@
<div class="text-xs mr-2 align-middle">
The variable you were looking for does not exist yet?
</div>
<button
class="default-button-secondary"
type="button"
<Button
variant="border"
color="blue"
size="sm"
on:click={() => {
variableEditor.initNew()
}}
>
Create a new variable
</button>
</Button>
</div>
</ItemPicker>
@@ -180,15 +181,16 @@
<div class="text-xs mr-2 align-middle">
The resource you were looking for does not exist yet?
</div>
<button
class="default-button-secondary"
type="button"
<Button
variant="border"
color="blue"
size="sm"
on:click={() => {
resourceEditor.initNew()
}}
>
Create a new resource
</button>
</Button>
</div>
</ItemPicker>
@@ -1,8 +1,8 @@
<script lang="ts">
import { JobService, type Flow } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import { faClose, faPlay } from '@fortawesome/free-solid-svg-icons'
import { faClose, faPlay, faRefresh } from '@fortawesome/free-solid-svg-icons'
import { Button } from './common'
import { createEventDispatcher, getContext, onDestroy } from 'svelte'
import Icon from 'svelte-awesome'
import { flowStateStore } from './flows/flowState'
@@ -11,9 +11,8 @@
import type { FlowEditorContext } from './flows/types'
import { runFlowPreview } from './flows/utils'
import SchemaForm from './SchemaForm.svelte'
import FlowStatusViewer from '../components/FlowStatusViewer.svelte'
import { Button } from './common'
export let previewMode: 'upTo' | 'whole'
let jobId: string | undefined = undefined
@@ -72,7 +71,10 @@
</h3>
</div>
<Button
color="light"
variant="border"
size="lg"
color="dark"
btnClasses="!p-0 !w-8 !h-8"
on:click={() => {
jobId = undefined
intervalState = 'idle'
@@ -90,38 +92,39 @@
bind:args={$previewArgs}
/>
</div>
<div class="w-full pt-1">
{#if intervalState === 'running'}
<Button
disabled={!isValid}
color="red"
btnClasses="w-full"
on:click={async () => {
intervalState = 'canceled'
try {
jobId &&
(await JobService.cancelQueuedJob({
workspace: $workspaceStore ?? '',
id: jobId,
requestBody: {}
}))
} catch {}
}}
size="md"
>
Cancel
</Button>
{:else}
<Button
disabled={!isValid}
btnClasses="w-full"
on:click={() => runPreview($previewArgs)}
size="md"
>
{`Run${intervalState === 'done' ? ' again' : ''}`}
</Button>
{/if}
</div>
{#if intervalState === 'running'}
<Button
disabled={!isValid}
color="red"
on:click={async () => {
intervalState = 'canceled'
try {
jobId &&
(await JobService.cancelQueuedJob({
workspace: $workspaceStore ?? '',
id: jobId,
requestBody: {}
}))
} catch {}
jobId = undefined
}}
size="md"
>
Cancel
</Button>
{:else}
<Button
variant="contained"
endIcon={{ icon: intervalState === 'done' ? faRefresh : faPlay }}
size="lg"
color="blue"
btnClasses="w-full"
disabled={!isValid}
on:click={() => runPreview($previewArgs)}
>
{`Run${intervalState === 'done' ? ' again' : ''}`}
</Button>
{/if}
<div class="h-full overflow-y-auto mb-16 grow">
{#if jobId}
+12 -12
View File
@@ -1,16 +1,14 @@
<script lang="ts">
import Highlight from 'svelte-highlight'
import json from 'svelte-highlight/languages/json'
import { faClipboard } from '@fortawesome/free-solid-svg-icons'
import type { FlowValue } from '$lib/gen'
import Tabs from './common/tabs/Tabs.svelte'
import Tab from './common/tabs/Tab.svelte'
import TabContent from './common/tabs/TabContent.svelte'
import { Tab, Tabs, TabContent, Button } from './common'
import SchemaViewer from './SchemaViewer.svelte'
import FieldHeader from './FieldHeader.svelte'
import SvelteMarkdown from 'svelte-markdown'
import FlowModulesViewer from './FlowModulesViewer.svelte'
import { copyToClipboard } from '../utils'
export let flow: {
summary: string
@@ -82,14 +80,16 @@
</TabContent>
<TabContent value="json">
<div class="relative">
<button
on:click={async () => {
await navigator.clipboard.writeText(JSON.stringify(flowFiltered, null, 4))
}}
class="absolute default-secondary-button-v2 bg-white/30 right-0 my-2 ml-4"
>
copy content</button
<Button
on:click={() => copyToClipboard(JSON.stringify(flowFiltered, null, 4))}
color="dark"
variant="border"
size="sm"
startIcon={{ icon: faClipboard }}
btnClasses="absolute top-2 right-2"
>
Copy content
</Button>
<Highlight language={json} code={JSON.stringify(flowFiltered, null, 4)} />
</div>
</TabContent>
+10 -2
View File
@@ -1,12 +1,12 @@
<script lang="ts">
import { userStore, workspaceStore } from '$lib/stores'
import Modal from './Modal.svelte'
import { type Group, GroupService, UserService } from '$lib/gen'
import AutoComplete from 'simple-svelte-autocomplete'
import PageHeader from './PageHeader.svelte'
import TableCustom from './TableCustom.svelte'
import { canWrite } from '$lib/utils'
import { Button } from './common'
let name = ''
let modal: Modal
@@ -62,7 +62,15 @@
{#if can_write}
<div>
<AutoComplete items={usernames} bind:selectedItem={username} />
<button class="default-button ml-4" on:click={addToGroup}>Add member</button>
<Button
variant="contained"
color="blue"
size="sm"
btnClasses="!ml-4"
on:click={addToGroup}
>
Add member
</Button>
</div>
{/if}
</PageHeader>
@@ -11,7 +11,7 @@
import { codeToStaticTemplate, getDefaultExpr, isCodeInjection } from './flows/utils'
import SimpleEditor from './SimpleEditor.svelte'
import Toggle from './Toggle.svelte'
import { Button } from 'flowbite-svelte'
import { Button } from './common'
import Icon from 'svelte-awesome'
import { faChain } from '@fortawesome/free-solid-svg-icons'
@@ -129,7 +129,7 @@
})
}}
>
<Button size="sm" class="blue-button">
<Button variant="contained" color="blue" size="md">
<Icon data={faChain} />
</Button>
</div>
@@ -13,7 +13,7 @@
<span class="font-black text-gray-700">{key}</span>: {#if val.type == 'static'}<ObjectViewer
json={val.value}
/>{:else}
<span class="inline-highlight">
<span class="text-xs">
<Highlight offsetTop={0} language={typescript} code={val.expr} />
</span>
{/if}
@@ -1,15 +1,13 @@
<script lang="ts">
import { sendUserToast } from '$lib/utils'
import Switch from './Switch.svelte'
import type Modal from './Modal.svelte'
import { createEventDispatcher } from 'svelte'
import { UserService } from '$lib/gen'
import { Button } from './common'
const dispatch = createEventDispatcher()
let valid = true
let modal: Modal
export function openModal(): void {
@@ -53,14 +51,14 @@
<input on:keyup={handleKeyUp} placeholder="name" bind:value={name} />
<input on:keyup={handleKeyUp} placeholder="company" bind:value={company} />
<button
class="ml-4 w-40 {valid ? 'default-button' : 'default-button-disabled'}"
type="button"
on:click={() => {
addUser()
}}
<Button
variant="contained"
color="blue"
size="sm"
btnClasses="!ml-4 !w-40"
on:click={addUser}
disabled={email == undefined || password == undefined}
>
Add
</button>
</Button>
</div>
+9 -11
View File
@@ -1,16 +1,14 @@
<script lang="ts">
import { sendUserToast } from '$lib/utils'
import Switch from './Switch.svelte'
import type Modal from './Modal.svelte'
import { createEventDispatcher } from 'svelte'
import { workspaceStore } from '$lib/stores'
import { WorkspaceService } from '$lib/gen'
import { Button } from './common'
const dispatch = createEventDispatcher()
let valid = true
let modal: Modal
export function openModal(): void {
@@ -45,14 +43,14 @@
<input on:keyup={handleKeyUp} placeholder="email" bind:value={email} />
<Switch class="ml-2" bind:checked={is_admin} horizontal={true} label={'admin: '} />
<button
class="ml-4 w-40 {valid ? 'default-button' : 'default-button-disabled'}"
type="button"
on:click={() => {
inviteUser()
}}
disabled={email == undefined}
<Button
variant="contained"
color="blue"
size="sm"
btnClasses="!ml-4"
on:click={inviteUser}
disabled={email === undefined}
>
Invite
</button>
</Button>
</div>
+1 -1
View File
@@ -208,7 +208,7 @@
</div>
<div class="pt-0 text-xs px-1 flex flex-col-reverse sm:grid sm:grid-cols-4 sm:gap-4 w-full">
<div class="col-span-2"><span class="font-mono">{path}</span></div>
<div class="text-purple-500 text-2xs col-span-2">{error}</div>
<div class="text-red-600 text-2xs col-span-2">{error}</div>
</div>
</div>
@@ -14,8 +14,9 @@
<div class="flex flex-row flex-wrap gap-2 items-center mb-2 w-full">
{#each options as [label, val]}
<label
class:item-button-selected={val == value}
class="item-button text-center text-sm h-full p-2 grow whitespace-nowrap"
class="text-center text-sm border border-gray-300 h-full rounded-sm cursor-pointer p-2
grow whitespace-nowrap hover:border-gray-600 hover:bg-gray-100
{val === value ? '!bg-blue-50 !border-blue-500' : ''}"
>
<input
type="radio"
@@ -10,6 +10,7 @@
import ItemPicker from './ItemPicker.svelte'
import VariableEditor from './VariableEditor.svelte'
import Required from './Required.svelte'
import { Button } from './common'
import { workspaceStore } from '$lib/stores'
import ResourceTypePicker from './ResourceTypePicker.svelte'
@@ -107,6 +108,10 @@
}
}
function resourceAction() {
return resourceToEdit ? editResource() : createResource()
}
let inputCheck: { [id: string]: boolean } = {}
$: isValid = allTrue(inputCheck) ?? false
@@ -124,7 +129,7 @@
{#if step === 1}
<div class="flex flex-col gap-3 px-6 py-3 bg-gray-50 text-gray-700">
<div>
<span class="text-purple-500 text-2xs grow">{error ?? ''}</span>
<span class="text-red-600 text-2xs grow">{error ?? ''}</span>
<span class="mb-1 font-semibold text-gray-700">Path</span>
<Path
bind:error={pathError}
@@ -183,13 +188,16 @@
properties={resourceSchema.properties[fieldName]?.properties}
format={resourceSchema.properties[fieldName]?.format}
/>
<div class="pb-3 ml-2 relative">
<button
class="default-button-secondary min-w-min items-center leading-4 py-0"
<div class="pb-6 ml-2 relative">
<Button
variant="border"
color="blue"
size="sm"
btnClasses="min-w-min items-center leading-4 py-0"
on:click={() => {
pickForField = fieldName
itemPicker.openModal()
}}>insert variable</button
}}>Insert variable</Button
>
</div>
</div>
@@ -200,10 +208,9 @@
</div>
{/if}
</div>
<span slot="submission">
<span slot="submission" class="flex gap-4">
{#if step === 1}
<button
class="default-button px-4 py-2 font-semibold"
<Button
on:click={async () => {
await loadResourceType()
step = 2
@@ -211,29 +218,10 @@
disabled={selectedResourceType == undefined || pathError != ''}
>
Next
</button>
</Button>
{:else}
<button
class="default-button-secondary px-4 py-2 font-semibold"
on:click={() => {
step = 1
}}
>
Back
</button>
<button
disabled={!isValid}
class="default-button px-4 py-2 font-semibold"
on:click={() => {
if (resourceToEdit) {
editResource()
} else {
createResource()
}
}}
>
Save
</button>
<Button variant="border" on:click={() => (step = 1)}>Back</Button>
<Button on:click={resourceAction} disabled={!isValid}>Save</Button>
{/if}
</span>
</Modal>
@@ -257,15 +245,16 @@
slot="submission"
class="flex flex-row-reverse w-full p-5 bg-white border-t border-gray-200 rounded-bl-lg rounded-br-lg"
>
<button
class="default-button-secondary"
type="button"
<Button
variant="border"
color="blue"
size="sm"
on:click={() => {
variableEditor.initNew()
}}
>
Create a new variable
</button>
</Button>
<div class="text-xs mr-2 align-middle">
The variable you were looking for does not exist yet?
</div>
@@ -4,6 +4,7 @@
import { ResourceService } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import IconedResourceType from './IconedResourceType.svelte'
import { Button } from './common'
let resources: string[] = []
@@ -18,48 +19,39 @@
const dispatch = createEventDispatcher()
$: {
if ($workspaceStore) {
loadResources()
}
function onClick(resource: string | undefined) {
value = resource
dispatch('click')
}
$: if ($workspaceStore) {
loadResources()
}
</script>
<div class="grid sm:grid-cols-2 md:grid-cols-3 gap-x-2 gap-y-1 items-center mb-2">
{#if nonePickable}
<button
class="px-4 h-8 text-center {undefined == value
? 'item-button-selected'
: notPickable
? 'item-button-disabled'
: 'item-button'}"
on:click={() => {
value = undefined
dispatch('click')
}}
{@const isPicked = value === undefined}
<Button
variant="border"
color={isPicked ? 'blue' : 'dark'}
btnClasses={isPicked ? '!border-2 !bg-blue-50/75' : 'm-[1px]'}
disabled={notPickable}
on:click={() => onClick(undefined)}
>
None
</button>
</Button>
{/if}
{#each resources as r}
<button
class="px-4 h-8 text-center {r == value
? 'item-button-selected'
: notPickable
? 'item-button-disabled'
: 'item-button'}"
on:click={() => {
value = r
dispatch('click')
}}
{@const isPicked = value === r}
<Button
variant="border"
color={isPicked ? 'blue' : 'dark'}
btnClasses={isPicked ? '!border-2 !bg-blue-50/75' : 'm-[1px]'}
disabled={notPickable}
on:click={() => onClick(r)}
>
<IconedResourceType name={r} after={true} />
</button>
</Button>
{/each}
</div>
<style>
.selected:hover {
@apply border border-gray-400 rounded-md border-opacity-50;
}
</style>
+23 -31
View File
@@ -10,6 +10,7 @@
import SchemaForm from './SchemaForm.svelte'
import Tooltip from './Tooltip.svelte'
import type { Schema } from '$lib/common'
import { Button } from './common'
export let runnable: { summary?: string; schema?: Schema; description?: string } | undefined
export let runAction: (scheduledForStr: string | undefined, args: Record<string, any>) => void
@@ -37,7 +38,7 @@
let scheduledForStr: string | undefined
</script>
<div class="max-w-5xl">
<div class="max-w-6xl">
{#if detailed}
<div class="grid grid-cols-3 gap-2">
<div>
@@ -91,55 +92,46 @@
min={getToday().toISOString().slice(0, 16)}
/>
</div>
<button
class="default-button-secondary mx-2 mb-1"
<Button
variant="border"
color="blue"
size="sm"
btnClasses="mx-2 mb-1"
on:click={() => {
scheduledForStr = undefined
}}
>
Clear
</button>
</Button>
</div>
</div>
</div>
{/if}
{#if schedulable}
<div class="flex justify-between mt-2 md:mt-6 mb-6">
<button
type="submit"
class="mr-6 text-sm underline text-gray-700 inline-flex items-center"
on:click={() => {
viewOptions = !viewOptions
}}
<Button
color="light"
size="sm"
endIcon={{ icon: viewOptions ? faChevronUp : faChevronDown }}
on:click={() => (viewOptions = !viewOptions)}
>
<div>
Schedule to run later
<Icon data={viewOptions ? faChevronUp : faChevronDown} scale={0.5} />
</div>
</button>
<button
type="submit"
Schedule to run later
</Button>
<Button
btnClasses="!px-6 !py-1"
disabled={!isValid}
class="{isValid ? 'default-button' : 'default-button-disabled'} w-min px-6"
on:click={() => {
runAction(scheduledForStr, args)
}}
on:click={() => runAction(scheduledForStr, args)}
>
{scheduledForStr ? 'Schedule run to a later time' : buttonText}
</button>
</Button>
</div>
{:else}
<button
type="submit"
<Button
btnClasses="!px-6 !py-1"
disabled={!isValid}
class="{isValid
? 'default-button'
: 'default-button-disabled'} w-full rounded rounded-md px-6 mb-4"
on:click={() => {
runAction(undefined, args)
}}
on:click={() => runAction(undefined, args)}
>
{buttonText}
</button>
</Button>
{/if}
</div>
+16 -10
View File
@@ -2,9 +2,8 @@
import type { Schema, SchemaProperty } from '$lib/common'
import { emptySchema, sendUserToast } from '$lib/utils'
import { faPen, faPlus, faTrash } from '@fortawesome/free-solid-svg-icons'
import { Button } from 'flowbite-svelte'
import { Button } from './common'
import { createEventDispatcher } from 'svelte'
import Icon from 'svelte-awesome'
import SchemaEditorProperty from './SchemaEditorProperty.svelte'
import type { ModalSchemaProperty } from './SchemaModal.svelte'
import SchemaModal, { DEFAULT_PROPERTY, schemaToModal } from './SchemaModal.svelte'
@@ -142,13 +141,15 @@
<div class="flex flex-col">
<div class="flex justify-between gap-x-2">
<Button
variant="contained"
color="blue"
size="md"
startIcon={{ icon: faPlus }}
on:click={() => {
modalProperty = Object.assign({}, DEFAULT_PROPERTY)
schemaModal.openModal()
}}
class="blue-button"
>
<Icon data={faPlus} class="mr-1" />
Add argument
</Button>
@@ -199,16 +200,21 @@
<td class="justify-end flex">
<Button
color="red"
outline
class="mr-2"
size="xs"
variant="border"
btnClasses="mr-2"
size="sm"
startIcon={{ icon: faTrash }}
on:click={() => handleDeleteArgument(name)}
>
<Icon data={faTrash} class="mr-2" scale={0.8} />
Delete
</Button>
<Button color="alternative" size="xs" on:click={() => startEditArgument(name)}>
<Icon data={faPen} class="mr-2" scale={0.8} />
<Button
color="light"
variant="border"
size="sm"
startIcon={{ icon: faPen }}
on:click={() => startEditArgument(name)}
>
Edit
</Button>
</td>
+18 -7
View File
@@ -50,6 +50,7 @@
import StringTypeNarrowing from './StringTypeNarrowing.svelte'
import Required from './Required.svelte'
import ObjectTypeNarrowing from './ObjectTypeNarrowing.svelte'
import { Button } from './common'
export let property: ModalSchemaProperty = DEFAULT_PROPERTY
export let error = ''
@@ -111,7 +112,7 @@
: 'border border-red-700 bg-red-100 border-opacity-30 focus:border-red-700 focus:border-opacity-30 focus-visible:ring-red-700 focus-visible:ring-opacity-25 focus-visible:border-red-700'}
/>
</label>
<div class="mb-2 text-purple-500 text-2xs">{error}</div>
<div class="mb-2 text-red-600 text-2xs">{error}</div>
<label class="mb-2 font-semibold text-gray-700">
Description
@@ -126,22 +127,32 @@
<h3 class="font-semibold text-gray-700">Type<Required required={true} /></h3>
<div class="grid sm:grid-cols-3 md:grid-cols-4 gap-x-2 gap-y-1 items-center mb-2 w-full">
{#each ARG_TYPES as argType}
<button
class={argType == property.selectedType ? 'item-button-selected' : 'item-button'}
{@const isSelected = argType == property.selectedType}
<Button
variant="border"
color={isSelected ? 'blue' : 'dark'}
btnClasses={isSelected ? '!border-2 !bg-blue-50/75' : 'm-[1px]'}
on:click={() => {
property.selectedType = argType
property.format = undefined
property.contentEncoding = undefined
property.enum_ = undefined
property.pattern = undefined
}}>{argType}</button
}}
>
{argType}
</Button>
{/each}
<button
class={!property.selectedType ? 'item-button-selected' : 'item-button'}
<Button
variant="border"
color={!property.selectedType ? 'blue' : 'dark'}
btnClasses={!property.selectedType ? '!border-2 !bg-blue-50/75' : 'm-[1px]'}
on:click={() => {
property.selectedType = undefined
}}>any</button
}}
>
Any
</Button>
>
</div>
<Switch
@@ -16,6 +16,7 @@
import ScriptSchema from './ScriptSchema.svelte'
import CenteredPage from './CenteredPage.svelte'
import Tooltip from './Tooltip.svelte'
import { Button } from './common'
export let script: Script
export let initialPath: string = ''
@@ -105,37 +106,37 @@
</div>
<div class="flex flex-row-reverse ml-2">
{#if step != 3}
<button
disabled={step == 1 && pathError != ''}
class="default-button px-6 max-h-8"
on:click={() => {
changeStep(step + 1)
}}
<Button
size="sm"
disabled={step === 1 && pathError !== ''}
on:click={() => changeStep(step + 1)}
>
Next
</button>
</Button>
{:else}
<button class="default-button px-6 self-end" on:click={editScript}>Save</button>
<Button size="sm" on:click={editScript}>Save</Button>
{/if}
{#if step > 1}
<button
class="default-button-secondary px-6 max-h-8 mr-2"
on:click={async () => {
changeStep(step - 1)
}}
<Button
variant="border"
size="sm"
btnClasses="mr-2"
on:click={() => changeStep(step - 1)}
>
Back
</button>
</Button>
{/if}
{#if step == 2}
<button
class="default-button-secondary px-6 max-h-8 mr-2"
<Button
variant="border"
size="sm"
btnClasses="mr-2"
on:click={async () => {
editScript()
}}
>
Save (commit)
</button>
</Button>
{/if}
</div>
</div>
+21 -10
View File
@@ -13,6 +13,7 @@
import { getScriptByPath } from '$lib/utils'
import RadioButton from './RadioButton.svelte'
import { Button } from './common'
export let scriptPath: string | undefined = undefined
export let allowFlow = false
@@ -62,27 +63,37 @@
}}
/>
<div class="flex flex-row items-center space-x-5">
<div class="w-80">
<div class="flex flex-row flex-wrap items-center gap-4">
<div class="w-80 -mb-2">
{#if options.length > 1}
<RadioButton bind:value={itemKind} {options} />
{/if}
</div>
<input type="text" value={scriptPath ?? 'No path chosen yet'} disabled />
<button class="default-button text-gray-100" on:click={() => itemPicker.openModal()}
>Pick a {itemKind} path<Icon class="mx-4" data={faSearch} /></button
>
{#if scriptPath != undefined && scriptPath != ''}
<button
class="text-xs text-blue-500"
<div class="flex items-center grow gap-4">
<input type="text" value={scriptPath ?? 'No path chosen yet'} disabled />
<Button
size="sm"
endIcon={{ icon: faSearch }}
btnClasses="mx-auto whitespace-nowrap"
on:click={() => itemPicker.openModal()}
>
Pick a {itemKind} path
</Button>
</div>
{#if scriptPath !== undefined && scriptPath !== ''}
<Button
color="light"
size="xs"
on:click={async () => {
const { language, content } = await getScriptByPath(scriptPath ?? '')
code = content
lang = language
modalViewer.openModal()
}}>show code</button
}}
>
Show code
</Button>
{/if}
</div>
@@ -8,6 +8,7 @@
import { createEventDispatcher } from 'svelte'
import AutoComplete from 'simple-svelte-autocomplete'
import { workspaceStore } from '$lib/stores'
import { Button } from './common'
const dispatch = createEventDispatcher()
@@ -116,10 +117,9 @@
<span class="text-sm text-gray-700">Editor</span>
<input class="block mt-4" type="checkbox" bind:checked={write} />
</label>
<button
class="text-xs default-button max-h-6 place-self-end ml-2"
on:click={() => addAcl(newOwner, write)}>Add permission</button
>
<Button size="sm" btnClasses="ml-2" on:click={() => addAcl(newOwner, write)}>
Add permission
</Button>
</div>
<TableCustom>
<tr slot="header-row">
@@ -133,8 +133,8 @@
<td>{owner}</td>
<td>{write}</td>
<td
><button class="default-button-secondary" on:click={() => deleteAcl(owner)}
>Delete</button
><Button variant="border" color="blue" size="sm" on:click={() => deleteAcl(owner)}
>Delete</Button
></td
>
</tr>
@@ -1,6 +1,7 @@
<script lang="ts">
import RadioButton from './RadioButton.svelte'
import ResourceTypePicker from './ResourceTypePicker.svelte'
import { Button } from './common'
export let pattern: string | undefined
export let enum_: string[] | undefined
@@ -29,6 +30,17 @@
kind == 'resource' ? (resource != undefined ? `resource-${resource}` : 'resource') : undefined
$: pattern = patternStr == '' ? undefined : patternStr
$: contentEncoding = kind == 'base64' ? 'base64' : undefined
function add() {
enum_ = enum_ ? enum_.concat('') : ['']
}
function remove(item: string) {
enum_ = (enum_ || []).filter((el) => el !== item)
if (enum_.length == 0) {
enum_ = undefined
}
}
</script>
<RadioButton
@@ -55,47 +67,31 @@
placeholder="^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
bind:value={patternStr}
/>
<button
class="default-button-secondary mx-2 mb-1"
<Button
variant="border"
color="blue"
size="sm"
btnClasses="mx-2 mb-1"
on:click={() => {
patternStr = ''
}}>clear</button
}}>clear</Button
>
</div>
</label>
{:else if kind == 'enum'}
<label for="input" class="mb-2 text-gray-700 text-xs"
>Enums
{#each enum_ ?? [] as e}
<label for="input" class="mb-2 text-gray-700 text-xs">
Enums
{#each enum_ || [] as e}
<div class="flex flex-row max-w-md">
<input id="input" type="text" bind:value={e} />
<button
class="default-button mx-6"
on:click={() => {
enum_ = (enum_ ?? []).filter((el) => el != e)
if (enum_.length == 0) {
enum_ = undefined
}
}}>-</button
>
<Button size="sm" btnClasses="ml-6" on:click={() => remove(e)}>-</Button>
</div>
{/each}
<div class="flex flex-row my-1">
<button
class="default-button"
on:click={() => {
if (enum_ == undefined) {
enum_ = []
}
enum_ = enum_.concat('')
}}>+</button
>
<button
class="default-button-secondary ml-2"
on:click={() => {
enum_ = undefined
}}>clear</button
>
<Button size="sm" on:click={add}>+</Button>
<Button variant="border" size="sm" btnClasses="ml-2" on:click={() => (enum_ = undefined)}>
Clear
</Button>
</div>
</label>
{:else if kind == 'resource'}
+1 -1
View File
@@ -58,6 +58,6 @@
<style>
#tooltip {
@apply z-50 text-base font-normal text-gray-300 bg-zinc-800 p-4 rounded-xl whitespace-normal;
@apply z-50 text-base font-normal text-gray-300 bg-gray-800 p-4 rounded-xl whitespace-normal;
}
</style>
@@ -9,6 +9,7 @@
import { workspaceStore } from '$lib/stores'
import Required from './Required.svelte'
import Tooltip from './Tooltip.svelte'
import { Button } from './common'
const dispatch = createEventDispatcher()
@@ -172,23 +173,11 @@
</div>
</div>
<button
slot="submission"
class={valid ? 'default-button' : 'default-button-disabled'}
type="button"
on:click={() => {
if (edit) {
updateVariable()
} else {
createVariable()
}
}}
<Button
size="sm"
on:click={() => (edit ? updateVariable() : createVariable())}
disabled={!valid || pathError != ''}
>
{#if edit}
Save
{:else}
Add a variable
{/if}
</button>
{edit ? 'Save' : 'Add a variable'}
</Button>
</Modal>
@@ -27,16 +27,12 @@
green: 'bg-green-100 text-green-800 dark:bg-green-200 dark:text-green-900',
yellow: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-200 dark:text-yellow-900',
indigo: 'bg-indigo-100 text-indigo-800 dark:bg-indigo-200 dark:text-indigo-900',
purple: 'bg-purple-100 text-purple-800 dark:bg-purple-200 dark:text-purple-900',
pink: 'bg-pink-100 text-pink-800 dark:bg-pink-200 dark:text-pink-900',
['dark-gray']: 'bg-gray-500 text-gray-100',
['dark-blue']: 'bg-blue-500 text-blue-100',
['dark-red']: 'bg-red-500 text-white',
['dark-green']: 'bg-green-500 text-green-100',
['dark-yellow']: 'bg-yellow-300 text-yellow-800',
['dark-indigo']: 'bg-indigo-500 text-indigo-100',
['dark-purple']: 'bg-purple-500 text-purple-100',
['dark-pink']: 'bg-pink-500 text-pink-100'
['dark-indigo']: 'bg-indigo-500 text-indigo-100'
}
const hovers: Partial<Record<BadgeColor, string>> = {
gray: 'hover:bg-gray-200 dark:hover:bg-gray-300',
@@ -44,9 +40,7 @@
red: 'hover:bg-red-200 dark:hover:bg-red-300',
green: 'hover:bg-green-200 dark:hover:bg-green-300',
yellow: 'hover:bg-yellow-200 dark:hover:bg-yellow-300',
indigo: 'hover:bg-indigo-200 dark:hover:bg-indigo-300',
purple: 'hover:bg-purple-200 dark:hover:bg-purple-300',
pink: 'hover:bg-pink-200 dark:hover:bg-pink-300'
indigo: 'hover:bg-indigo-200 dark:hover:bg-indigo-300'
}
$: badgeClass = classNames(
@@ -1,6 +1,6 @@
import type { IconProps } from 'svelte-awesome/components/Icon.svelte'
type BaseColor = 'blue' | 'gray' | 'red' | 'green' | 'yellow' | 'indigo' | 'purple' | 'pink'
type BaseColor = 'blue' | 'gray' | 'red' | 'green' | 'yellow' | 'indigo'
export const ColorModifier = 'dark-'
export type BadgeColor = BaseColor | `${typeof ColorModifier}${BaseColor}`
@@ -26,8 +26,8 @@
},
red: {
border:
'border-red-500 hover:border-red-700 bg-white hover:bg-red-100 text-red-500 hover:text-red-700 focus:ring-red-300',
contained: 'bg-red-500 hover:bg-red-700 text-white focus:ring-red-300'
'border-red-600 hover:border-red-700 bg-white hover:bg-red-100 text-red-600 hover:text-red-700 focus:ring-red-300',
contained: 'bg-red-600 hover:bg-red-700 text-white focus:ring-red-300'
},
dark: {
border:
@@ -57,7 +57,7 @@
xl: 'px-4 py-2'
}
const iconScale: Record<Button.Size, number> = {
xs: 0.7,
xs: 0.6,
sm: 0.8,
md: 1,
lg: 1.1,
@@ -78,6 +78,10 @@
),
disabled
}
$: isSmall = size === 'xs' || size === 'sm'
$: startIconClass = classNames(isSmall ? 'mr-1' : 'mr-2', startIcon?.classes)
$: endIconClass = classNames(isSmall ? 'ml-1' : 'ml-2', endIcon?.classes)
</script>
{#if href}
@@ -107,7 +111,7 @@
{/if}
</button>
{:else}
<button type="button" on:click|stopPropagation {...buttonProps}>
<button type="button" on:click|stopPropagation {...buttonProps} {...$$restProps}>
{#if startIcon}
<Icon
data={startIcon.icon}
@@ -9,6 +9,7 @@
import { sendUserToast } from '$lib/utils'
import { faFileExport, faFileImport, faGlobe } from '@fortawesome/free-solid-svg-icons'
import Icon from 'svelte-awesome'
import { Button } from '../../common'
import { flowStore, initFlow } from '../flowStore'
import { cleanInputs } from '../utils'
@@ -46,9 +47,7 @@
<Drawer bind:this={jsonSetterDrawer} size="800px">
<DrawerContent title="Import JSON" on:close={() => jsonSetterDrawer.toggleDrawer()}>
<button class="default-button px-4 py-2 font-semibold" on:click={() => importJson()}>
Import
</button>
<Button size="sm" on:click={importJson}>Import</Button>
<SimpleEditor bind:code={pendingJson} lang="json" class="h-full" />
</DrawerContent>
</Drawer>
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 50 50"
style=" fill:#000000;"
style="fill:currentcolor;"
>
<path
d="M 24.505859 4.0078125 C 23.980484 4.0080625 23.454344 4.1114062 22.964844 4.3164062 L 4.2226562 11.646484 C 3.4796562 11.959484 3 12.683281 3 13.488281 C 2.999 14.293281 3.4771406 15.017797 4.2441406 15.341797 L 23.236328 22.775391 C 23.613328 22.935391 24.018969 23.013672 24.417969 23.013672 C 24.802969 23.013672 25.181391 22.939875 25.525391 22.796875 L 45.771484 15.330078 C 46.519484 15.018078 47.001953 14.292422 47.001953 13.482422 C 47.000953 12.672422 46.516422 11.949047 45.732422 11.623047 L 26.046875 4.3144531 C 25.556875 4.1104531 25.031234 4.0075625 24.505859 4.0078125 z M 24.498047 6.0097656 C 24.770047 6.0097656 25.0455 6.0647813 25.3125 6.1757812 L 45.041016 13.46875 L 24.794922 20.935547 C 24.551922 21.039547 24.266188 21.039828 23.992188 20.923828 L 4.9765625 13.5 L 23.705078 6.1738281 L 23.728516 6.1640625 C 23.972516 6.0610625 24.233047 6.0097656 24.498047 6.0097656 z M 1.9980469 17.001953 C 0.94204687 17.001953 -2.9605947e-16 17.853906 0 19.003906 L 0 34.970703 C 0 36.129703 0.95195312 36.972656 2.0019531 36.972656 C 2.2979531 36.972656 2.6015312 36.906766 2.8945312 36.759766 L 20.894531 27.998047 C 22.425531 27.232047 22.349531 25.022281 20.769531 24.363281 L 2.7695312 17.15625 C 2.5135313 17.05125 2.2520469 17.001953 1.9980469 17.001953 z M 48.001953 17.001953 C 47.760953 17.001953 47.514484 17.045625 47.271484 17.140625 L 28.271484 24.505859 C 27.505484 24.806859 27 25.544188 27 26.367188 L 27 42.998047 C 27 44.146047 27.940047 45 28.998047 45 C 29.239047 45 29.485516 44.956328 29.728516 44.861328 L 48.728516 37.425781 C 49.495516 37.125781 50 36.387453 50 35.564453 L 50 19.003906 C 50 17.855906 49.059953 17.001953 48.001953 17.001953 z M 2.0058594 19.003906 L 2.0253906 19.013672 L 20.017578 26.201172 L 2 34.970703 L 2.0058594 19.003906 z M 48 19.003906 L 48 35.564453 L 29 42.998047 L 28.994141 26.371094 L 48 19.003906 z"
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 50 50"
style=" fill:#000000;"
style="fill:currentcolor;"
><path
d="M 18.90625 7 C 18.90625 7 12.539063 7.4375 8.375 10.78125 C 8.355469 10.789063 8.332031 10.800781 8.3125 10.8125 C 7.589844 11.480469 7.046875 12.515625 6.375 14 C 5.703125 15.484375 4.992188 17.394531 4.34375 19.53125 C 3.050781 23.808594 2 29.058594 2 34 C 1.996094 34.175781 2.039063 34.347656 2.125 34.5 C 3.585938 37.066406 6.273438 38.617188 8.78125 39.59375 C 11.289063 40.570313 13.605469 40.960938 14.78125 41 C 15.113281 41.011719 15.429688 40.859375 15.625 40.59375 L 18.0625 37.21875 C 20.027344 37.683594 22.332031 38 25 38 C 27.667969 38 29.972656 37.683594 31.9375 37.21875 L 34.375 40.59375 C 34.570313 40.859375 34.886719 41.011719 35.21875 41 C 36.394531 40.960938 38.710938 40.570313 41.21875 39.59375 C 43.726563 38.617188 46.414063 37.066406 47.875 34.5 C 47.960938 34.347656 48.003906 34.175781 48 34 C 48 29.058594 46.949219 23.808594 45.65625 19.53125 C 45.007813 17.394531 44.296875 15.484375 43.625 14 C 42.953125 12.515625 42.410156 11.480469 41.6875 10.8125 C 41.667969 10.800781 41.644531 10.789063 41.625 10.78125 C 37.460938 7.4375 31.09375 7 31.09375 7 C 31.019531 6.992188 30.949219 6.992188 30.875 7 C 30.527344 7.046875 30.234375 7.273438 30.09375 7.59375 C 30.09375 7.59375 29.753906 8.339844 29.53125 9.40625 C 27.582031 9.09375 25.941406 9 25 9 C 24.058594 9 22.417969 9.09375 20.46875 9.40625 C 20.246094 8.339844 19.90625 7.59375 19.90625 7.59375 C 19.734375 7.203125 19.332031 6.964844 18.90625 7 Z M 18.28125 9.15625 C 18.355469 9.359375 18.40625 9.550781 18.46875 9.78125 C 16.214844 10.304688 13.746094 11.160156 11.4375 12.59375 C 11.074219 12.746094 10.835938 13.097656 10.824219 13.492188 C 10.816406 13.882813 11.039063 14.246094 11.390625 14.417969 C 11.746094 14.585938 12.167969 14.535156 12.46875 14.28125 C 17.101563 11.410156 22.996094 11 25 11 C 27.003906 11 32.898438 11.410156 37.53125 14.28125 C 37.832031 14.535156 38.253906 14.585938 38.609375 14.417969 C 38.960938 14.246094 39.183594 13.882813 39.175781 13.492188 C 39.164063 13.097656 38.925781 12.746094 38.5625 12.59375 C 36.253906 11.160156 33.785156 10.304688 31.53125 9.78125 C 31.59375 9.550781 31.644531 9.359375 31.71875 9.15625 C 32.859375 9.296875 37.292969 9.894531 40.3125 12.28125 C 40.507813 12.460938 41.1875 13.460938 41.8125 14.84375 C 42.4375 16.226563 43.09375 18.027344 43.71875 20.09375 C 44.9375 24.125 45.921875 29.097656 45.96875 33.65625 C 44.832031 35.496094 42.699219 36.863281 40.5 37.71875 C 38.5 38.496094 36.632813 38.84375 35.65625 38.9375 L 33.96875 36.65625 C 34.828125 36.378906 35.601563 36.078125 36.28125 35.78125 C 38.804688 34.671875 40.15625 33.5 40.15625 33.5 C 40.570313 33.128906 40.605469 32.492188 40.234375 32.078125 C 39.863281 31.664063 39.226563 31.628906 38.8125 32 C 38.8125 32 37.765625 32.957031 35.46875 33.96875 C 34.625 34.339844 33.601563 34.707031 32.4375 35.03125 C 32.167969 35 31.898438 35.078125 31.6875 35.25 C 29.824219 35.703125 27.609375 36 25 36 C 22.371094 36 20.152344 35.675781 18.28125 35.21875 C 18.070313 35.078125 17.8125 35.019531 17.5625 35.0625 C 16.394531 34.738281 15.378906 34.339844 14.53125 33.96875 C 12.234375 32.957031 11.1875 32 11.1875 32 C 10.960938 31.789063 10.648438 31.699219 10.34375 31.75 C 9.957031 31.808594 9.636719 32.085938 9.53125 32.464844 C 9.421875 32.839844 9.546875 33.246094 9.84375 33.5 C 9.84375 33.5 11.195313 34.671875 13.71875 35.78125 C 14.398438 36.078125 15.171875 36.378906 16.03125 36.65625 L 14.34375 38.9375 C 13.367188 38.84375 11.5 38.496094 9.5 37.71875 C 7.300781 36.863281 5.167969 35.496094 4.03125 33.65625 C 4.078125 29.097656 5.0625 24.125 6.28125 20.09375 C 6.90625 18.027344 7.5625 16.226563 8.1875 14.84375 C 8.8125 13.460938 9.492188 12.460938 9.6875 12.28125 C 12.707031 9.894531 17.140625 9.296875 18.28125 9.15625 Z M 18.5 21 C 15.949219 21 14 23.316406 14 26 C 14 28.683594 15.949219 31 18.5 31 C 21.050781 31 23 28.683594 23 26 C 23 23.316406 21.050781 21 18.5 21 Z M 31.5 21 C 28.949219 21 27 23.316406 27 26 C 27 28.683594 28.949219 31 31.5 31 C 34.050781 31 36 28.683594 36 26 C 36 23.316406 34.050781 21 31.5 21 Z M 18.5 23 C 19.816406 23 21 24.265625 21 26 C 21 27.734375 19.816406 29 18.5 29 C 17.183594 29 16 27.734375 16 26 C 16 24.265625 17.183594 23 18.5 23 Z M 31.5 23 C 32.816406 23 34 24.265625 34 26 C 34 27.734375 32.816406 29 31.5 29 C 30.183594 29 29 27.734375 29 26 C 29 24.265625 30.183594 23 31.5 23 Z"
/></svg
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 50 50"
style=" fill:#000000;"
style="fill:currentcolor;"
><path
d="M 15.6875 4 C 14.113281 4 12.652344 4.867188 11.875 6.25 L 2.59375 22.78125 C 1.816406 24.160156 1.816406 25.839844 2.59375 27.21875 L 11.875 43.75 C 12.652344 45.132813 14.113281 46 15.6875 46 L 34.3125 46 C 35.886719 46 37.347656 45.132813 38.125 43.75 L 47.40625 27.21875 C 48.183594 25.839844 48.183594 24.160156 47.40625 22.78125 L 38.125 6.25 C 37.347656 4.867188 35.886719 4 34.3125 4 Z M 15.6875 6 L 34.3125 6 C 35.15625 6 35.941406 6.449219 36.375 7.21875 L 39.0625 12 L 17.5 12 L 17.21875 12.5 L 11.15625 23 L 7.90625 17.375 L 13.625 7.21875 C 14.058594 6.449219 14.84375 6 15.6875 6 Z M 18.65625 14 L 31.34375 14 L 37.71875 25 L 34.125 31.21875 L 31.34375 36 L 18.65625 36 L 17.5 34.03125 L 14.90625 29.53125 L 12.28125 25 Z M 33.65625 14 L 40.1875 14 L 45.6875 23.75 C 46.121094 24.519531 46.121094 25.480469 45.6875 26.25 L 36.375 42.78125 C 35.941406 43.550781 35.15625 44 34.3125 44 L 29.0625 44 L 32.5 38 L 32.78125 37.5 L 39.71875 25.5 L 40 25 L 39.71875 24.5 Z M 25 19 C 21.699219 19 19 21.699219 19 25 C 19 28.300781 21.699219 31 25 31 C 28.300781 31 31 28.300781 31 25 C 31 21.699219 28.300781 19 25 19 Z M 6.75 19.40625 L 10 25 L 10.28125 25.5 L 15.78125 35.03125 L 17.21875 37.5 L 17.5 38 L 30.1875 38 L 26.71875 44 L 15.6875 44 C 14.84375 44 14.058594 43.550781 13.625 42.78125 L 4.3125 26.25 C 3.878906 25.480469 3.878906 24.519531 4.3125 23.75 Z M 25 21 C 27.222656 21 29 22.777344 29 25 C 29 27.222656 27.222656 29 25 29 C 22.777344 29 21 27.222656 21 25 C 21 22.777344 22.777344 21 25 21 Z"
/></svg
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 50 50"
style=" fill:#000000;"
style="fill:currentcolor;"
><path
d="M 38.011719 4 C 37.574219 3.996094 37.183594 4.273438 37.046875 4.691406 L 32.074219 20 L 17.925781 20 L 12.953125 4.691406 C 12.820313 4.289063 12.449219 4.011719 12.023438 4 C 11.597656 3.992188 11.214844 4.25 11.0625 4.648438 L 5.070313 20.640625 C 5.066406 20.640625 5.066406 20.644531 5.0625 20.648438 L 2.0625 28.648438 C 1.90625 29.070313 2.046875 29.542969 2.414063 29.808594 L 24.40625 45.800781 L 24.410156 45.808594 C 24.414063 45.808594 24.414063 45.808594 24.414063 45.8125 C 24.425781 45.820313 24.441406 45.828125 24.453125 45.835938 C 24.46875 45.84375 24.480469 45.855469 24.496094 45.863281 C 24.5 45.863281 24.5 45.867188 24.503906 45.867188 C 24.503906 45.867188 24.507813 45.871094 24.511719 45.871094 C 24.515625 45.875 24.519531 45.878906 24.527344 45.878906 C 24.53125 45.882813 24.539063 45.886719 24.542969 45.890625 C 24.5625 45.898438 24.585938 45.910156 24.609375 45.917969 C 24.609375 45.917969 24.609375 45.917969 24.609375 45.921875 C 24.632813 45.929688 24.65625 45.9375 24.675781 45.945313 C 24.679688 45.945313 24.679688 45.945313 24.683594 45.949219 C 24.699219 45.953125 24.714844 45.957031 24.734375 45.964844 C 24.742188 45.964844 24.75 45.96875 24.761719 45.96875 C 24.761719 45.972656 24.761719 45.972656 24.761719 45.96875 C 24.78125 45.976563 24.800781 45.980469 24.820313 45.984375 C 24.847656 45.988281 24.871094 45.992188 24.898438 45.996094 C 24.9375 45.996094 24.980469 46 25.019531 46 C 25.058594 45.996094 25.09375 45.996094 25.128906 45.988281 C 25.144531 45.988281 25.15625 45.988281 25.171875 45.984375 C 25.171875 45.984375 25.175781 45.984375 25.179688 45.984375 C 25.1875 45.980469 25.191406 45.980469 25.199219 45.980469 C 25.203125 45.980469 25.207031 45.976563 25.214844 45.976563 C 25.222656 45.972656 25.234375 45.972656 25.242188 45.96875 C 25.257813 45.964844 25.269531 45.960938 25.28125 45.957031 C 25.289063 45.957031 25.292969 45.957031 25.296875 45.953125 C 25.300781 45.953125 25.304688 45.953125 25.308594 45.953125 C 25.324219 45.945313 25.34375 45.9375 25.359375 45.933594 C 25.378906 45.925781 25.394531 45.917969 25.410156 45.910156 C 25.414063 45.910156 25.414063 45.910156 25.417969 45.90625 C 25.421875 45.90625 25.425781 45.90625 25.429688 45.902344 C 25.4375 45.898438 25.445313 45.894531 25.453125 45.890625 C 25.476563 45.878906 25.496094 45.867188 25.515625 45.855469 C 25.523438 45.851563 25.527344 45.847656 25.53125 45.84375 C 25.535156 45.84375 25.539063 45.839844 25.542969 45.839844 C 25.558594 45.828125 25.574219 45.820313 25.589844 45.808594 L 25.597656 45.796875 L 47.589844 29.808594 C 47.953125 29.542969 48.09375 29.070313 47.9375 28.648438 L 44.945313 20.675781 C 44.941406 20.667969 44.9375 20.65625 44.9375 20.648438 L 38.9375 4.648438 C 38.789063 4.261719 38.425781 4.003906 38.011719 4 Z M 11.933594 8.027344 L 15.824219 20 L 7.445313 20 Z M 38.066406 8.027344 L 42.558594 20 L 34.175781 20 Z M 8.066406 22 L 16.472656 22 L 22.328125 40.015625 Z M 18.578125 22 L 31.421875 22 L 25 41.765625 Z M 33.527344 22 L 41.933594 22 L 27.671875 40.015625 Z M 6.3125 23.007813 L 19.6875 39.902344 L 4.203125 28.640625 Z M 43.6875 23.007813 L 45.796875 28.640625 L 30.3125 39.902344 Z"
/></svg
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 50 50"
style=" fill:#000000;"
style="fill:currentcolor;"
><path
d="M 28.90625 1.96875 C 28.863281 1.976563 28.820313 1.988281 28.78125 2 L 11.5 2 C 9.585938 2 8 3.558594 8 5.46875 L 8 43.90625 C 8 46.160156 9.867188 48 12.125 48 L 37.875 48 C 40.132813 48 42 46.160156 42 43.90625 L 42 15.1875 C 42.027344 15.054688 42.027344 14.914063 42 14.78125 L 42 14.5 C 42.007813 14.234375 41.90625 13.972656 41.71875 13.78125 L 30.21875 2.28125 C 30.027344 2.09375 29.765625 1.992188 29.5 2 L 29.1875 2 C 29.097656 1.976563 29 1.964844 28.90625 1.96875 Z M 11.5 4 L 28 4 L 28 12.34375 C 28 14.355469 29.644531 16 31.65625 16 L 40 16 L 40 43.90625 C 40 45.074219 39.054688 46 37.875 46 L 12.125 46 C 10.945313 46 10 45.074219 10 43.90625 L 10 5.46875 C 10 4.644531 10.660156 4 11.5 4 Z M 30 4.9375 L 39.0625 14 L 31.65625 14 C 30.722656 14 30 13.277344 30 12.34375 Z M 17 24 L 17 38 L 33 38 L 33 24 Z M 19 26 L 24 26 L 24 28 L 19 28 Z M 26 26 L 31 26 L 31 28 L 26 28 Z M 19 30 L 24 30 L 24 32 L 19 32 Z M 26 30 L 31 30 L 31 32 L 26 32 Z M 19 34 L 24 34 L 24 36 L 19 36 Z M 26 34 L 31 34 L 31 36 L 26 36 Z"
/></svg
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 32 32"
style=" fill:#000000;"
style="fill:currentcolor;"
><path
d="M 6.9667969 4 C 5.8922226 4 5 4.8922226 5 5.9667969 L 5 8.3867188 C 4.6700827 8.5693007 4.3668503 8.8022905 4.1230469 9.1015625 C 3.5561678 9.7967647 3.3299502 10.7122 3.5097656 11.591797 L 3.5097656 11.59375 C 4.0409792 14.178038 4.7794422 17.772026 4.8261719 18 C 4.7795089 18.227574 4.0439586 21.806083 3.5136719 24.390625 C 3.33239 25.274562 3.5603689 26.193876 4.1289062 26.892578 L 4.1289062 26.894531 C 4.6989448 27.593193 5.5544182 28 6.4570312 28 L 25.501953 28 C 26.414029 28 27.27875 27.588847 27.855469 26.882812 L 27.855469 26.880859 C 28.431397 26.174017 28.661627 25.244791 28.478516 24.351562 C 27.948342 21.768542 27.220293 18.226607 27.173828 18 C 27.220578 17.771923 27.959908 14.172625 28.490234 11.587891 C 28.670205 10.710536 28.445474 9.7948488 27.878906 9.0996094 L 27.876953 9.0976562 C 27.633016 8.7986233 27.330145 8.566746 27 8.3847656 L 27 5.9667969 C 27 4.8922226 26.107777 4 25.033203 4 L 6.9667969 4 z M 7 6 L 25 6 L 25 8 L 7 8 L 7 6 z M 6.4414062 10 L 25 10 L 25 10.003906 L 25.580078 10.003906 C 25.870925 10.00932 26.145127 10.138539 26.328125 10.363281 C 26.516313 10.593787 26.591101 10.893775 26.53125 11.185547 C 25.98421 13.851742 25.173828 17.798828 25.173828 17.798828 L 25.132812 18 L 25.173828 18.201172 C 25.173828 18.201172 25.970539 22.088714 26.517578 24.753906 C 26.579608 25.059411 26.503358 25.374804 26.306641 25.617188 C 26.107355 25.861152 25.815878 26 25.501953 26 L 6.4570312 26 C 6.1536443 26 5.871649 25.864198 5.6796875 25.628906 C 5.4891549 25.393814 5.4120715 25.088382 5.4726562 24.792969 C 6.0196814 22.126846 6.8261719 18.201172 6.8261719 18.201172 L 6.8671875 18 L 6.8261719 17.798828 C 6.8261719 17.798828 6.0168603 13.857943 5.46875 11.191406 L 5.4707031 11.191406 C 5.4106381 10.897589 5.4835861 10.595863 5.671875 10.365234 L 5.6738281 10.365234 C 5.8620903 10.134148 6.1432948 10 6.4414062 10 z M 13.294922 13 C 12.044922 13 10.909797 13.341641 10.341797 13.681641 L 10.796875 15.271484 C 11.250875 15.044484 12.046797 14.703125 12.841797 14.703125 C 13.750797 14.703125 14.205078 15.158563 14.205078 15.726562 C 14.205078 16.521563 13.295 16.863281 12.5 16.863281 L 11.591797 16.863281 L 11.591797 18.453125 L 12.501953 18.453125 C 13.524953 18.453125 14.433594 18.909359 14.433594 19.818359 C 14.433594 20.500359 13.864516 21.068359 12.728516 21.068359 C 11.819516 21.068359 10.910078 20.727 10.455078 20.5 L 9.9980469 22.318359 C 10.566047 22.659359 11.589844 23 12.839844 23 C 15.339844 23 16.816406 21.749922 16.816406 20.044922 C 16.816406 18.681922 15.907484 17.885203 14.771484 17.658203 C 15.908484 17.203203 16.476562 16.409719 16.476562 15.386719 C 16.476562 14.023719 15.339922 13 13.294922 13 z M 19 13 L 19 23 L 21 23 L 21 13 L 19 13 z"
/></svg
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 32 32"
style=" fill:#000000;"
style="fill:currentcolor;"
><path
d="M 11.4375 5 L 11.15625 5.46875 L 3.15625 18.46875 L 2.84375 18.96875 L 3.125 19.5 L 7.125 26.5 L 7.40625 27 L 24.59375 27 L 24.875 26.5 L 28.875 19.5 L 29.15625 18.96875 L 28.84375 18.46875 L 20.84375 5.46875 L 20.5625 5 Z M 13.78125 7 L 19.4375 7 L 26.21875 18 L 20.5625 18 Z M 12 7.90625 L 14.96875 12.75 L 8.03125 24.03125 L 5.15625 19 Z M 16.15625 14.65625 L 18.21875 18 L 14.09375 18 Z M 12.875 20 L 26.28125 20 L 23.40625 25 L 9.78125 25 Z"
/></svg
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 30 30"
style=" fill:#000000;"
style="fill:currentcolor;"
>
<path
d="M15,3C8.373,3,3,8.373,3,15c0,5.623,3.872,10.328,9.092,11.63C12.036,26.468,12,26.28,12,26.047v-2.051 c-0.487,0-1.303,0-1.508,0c-0.821,0-1.551-0.353-1.905-1.009c-0.393-0.729-0.461-1.844-1.435-2.526 c-0.289-0.227-0.069-0.486,0.264-0.451c0.615,0.174,1.125,0.596,1.605,1.222c0.478,0.627,0.703,0.769,1.596,0.769 c0.433,0,1.081-0.025,1.691-0.121c0.328-0.833,0.895-1.6,1.588-1.962c-3.996-0.411-5.903-2.399-5.903-5.098 c0-1.162,0.495-2.286,1.336-3.233C9.053,10.647,8.706,8.73,9.435,8c1.798,0,2.885,1.166,3.146,1.481C13.477,9.174,14.461,9,15.495,9 c1.036,0,2.024,0.174,2.922,0.483C18.675,9.17,19.763,8,21.565,8c0.732,0.731,0.381,2.656,0.102,3.594 c0.836,0.945,1.328,2.066,1.328,3.226c0,2.697-1.904,4.684-5.894,5.097C18.199,20.49,19,22.1,19,23.313v2.734 c0,0.104-0.023,0.179-0.035,0.268C23.641,24.676,27,20.236,27,15C27,8.373,21.627,3,15,3z"
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 50 50"
style=" fill:#000000;"
style="fill:currentcolor;"
><path
d="M 43.753906 6.4023438 C 42.53621 6.3489969 41.294792 6.712898 40.271484 7.46875 L 37.525391 9.4960938 L 25 18.755859 L 12.591797 9.5839844 A 1.0001 1.0001 0 0 0 11.949219 9.3007812 L 12.199219 9.3007812 L 9.734375 7.4765625 C 8.7104042 6.7188363 7.4671493 6.3528895 6.2480469 6.40625 C 5.0289444 6.4596105 3.8349462 6.9314667 2.9082031 7.8457031 C 1.7309454 9.0063798 1 10.629831 1 12.410156 L 1 15.84375 A 1.0001 1.0001 0 0 0 1 16.138672 L 1 39.5 C 1 41.421188 2.5788117 43 4.5 43 L 12 43 A 1.0001 1.0001 0 0 0 13 42 L 13 25.373047 L 24.40625 33.804688 A 1.0001 1.0001 0 0 0 25.59375 33.804688 L 37 25.373047 L 37 42 A 1.0001 1.0001 0 0 0 38 43 L 45.5 43 C 47.421188 43 49 41.421188 49 39.5 L 49 16.119141 A 1.0001 1.0001 0 0 0 49 15.859375 L 49 12.410156 C 49 10.6517 48.290455 9.0357821 47.128906 7.8730469 C 47.095336 7.8394769 47.084086 7.83018 47.097656 7.84375 A 1.0001 1.0001 0 0 0 47.091797 7.8378906 C 46.165242 6.9256756 44.971603 6.4556905 43.753906 6.4023438 z M 43.644531 8.4003906 C 44.400835 8.4300436 45.134049 8.7168876 45.689453 9.2636719 C 45.708363 9.2823439 45.722171 9.2964424 45.712891 9.2871094 C 46.50934 10.084374 47 11.188613 47 12.410156 L 47 15.496094 L 39 21.408203 L 39 11 A 1.0001 1.0001 0 0 0 38.996094 10.898438 L 41.458984 9.078125 A 1.0001 1.0001 0 0 0 41.460938 9.078125 C 42.109578 8.598977 42.888228 8.3707375 43.644531 8.4003906 z M 6.3574219 8.40625 C 7.1145694 8.37661 7.8958927 8.6037105 8.5449219 9.0839844 L 11.003906 10.902344 A 1.0001 1.0001 0 0 0 11 11 L 11 21.408203 L 3 15.496094 L 3 12.410156 C 3 11.174482 3.5017577 10.068855 4.3125 9.2695312 C 4.8677569 8.7217677 5.6002743 8.4358895 6.3574219 8.40625 z M 37 12.371094 L 37 22.886719 L 25 31.755859 L 13 22.886719 L 13 12.373047 L 24.40625 20.804688 A 1.0001 1.0001 0 0 0 25.59375 20.804688 L 37 12.371094 z M 3 17.982422 L 11 23.896484 L 11 41 L 4.5 41 C 3.6591883 41 3 40.340812 3 39.5 L 3 17.982422 z M 47 17.982422 L 47 39.5 C 47 40.340812 46.340812 41 45.5 41 L 39 41 L 39 23.896484 L 47 17.982422 z"
/></svg
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 32 32"
style=" fill:#000000;"
style="fill:currentcolor;"
><path
d="M 15.9375 4.03125 C 12.917 4.0435 9.9179219 4.4269844 8.3574219 5.1464844 C 8.3574219 5.1464844 5 6.6748594 5 11.880859 C 5 18.077859 4.9955 25.860234 10.5625 27.365234 C 12.6945 27.938234 14.527953 28.061562 16.001953 27.976562 C 18.676953 27.825562 20 27.005859 20 27.005859 L 19.910156 25.029297 C 19.910156 25.029297 18.176297 25.640313 16.029297 25.570312 C 13.902297 25.495313 11.6615 25.335688 11.3125 22.679688 C 11.2805 22.432688 11.264625 22.182594 11.265625 21.933594 C 15.772625 23.052594 19.615828 22.420969 20.673828 22.292969 C 23.627828 21.933969 26.199344 20.081672 26.527344 18.388672 C 27.041344 15.720672 26.998047 11.880859 26.998047 11.880859 C 26.998047 6.6748594 23.646484 5.1464844 23.646484 5.1464844 C 22.000984 4.3779844 18.958 4.019 15.9375 4.03125 z M 12.705078 8.0019531 C 13.739953 8.0297031 14.762578 8.4927031 15.392578 9.4707031 L 16.001953 10.505859 L 16.609375 9.4707031 C 17.874375 7.5037031 20.709594 7.6264375 22.058594 9.1484375 C 23.302594 10.596438 23.025391 11.531 23.025391 18 L 23.025391 18.001953 L 20.578125 18.001953 L 20.578125 12.373047 C 20.578125 9.7380469 17.21875 9.6362812 17.21875 12.738281 L 17.21875 16 L 14.787109 16 L 14.787109 12.738281 C 14.787109 9.6362812 11.429688 9.7360938 11.429688 12.371094 L 11.429688 18 L 8.9765625 18 C 8.9765625 11.526 8.7043594 10.585438 9.9433594 9.1484375 C 10.622859 8.3824375 11.670203 7.9742031 12.705078 8.0019531 z"
/></svg
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 50 50"
style=" fill:#000000;"
style="fill:currentcolor;"
><path
d="M 5 5 A 1.0001 1.0001 0 0 0 4 6 L 4 44 A 1.0001 1.0001 0 0 0 5 45 L 8 45 A 1.0001 1.0001 0 1 0 8 43 L 6 43 L 6 7 L 8 7 A 1.0001 1.0001 0 1 0 8 5 L 5 5 z M 42 5 A 1.0001 1.0001 0 1 0 42 7 L 44 7 L 44 43 L 42 43 A 1.0001 1.0001 0 1 0 42 45 L 45 45 A 1.0001 1.0001 0 0 0 46 44 L 46 6 A 1.0001 1.0001 0 0 0 45 5 L 42 5 z M 31.074219 17.509766 C 29.975744 17.487506 28.868391 17.760297 27.978516 18.373047 C 27.407516 18.767047 26.915609 19.272813 26.349609 19.757812 C 25.488609 18.039813 23.929344 17.580781 22.152344 17.550781 C 20.351344 17.519781 18.920922 18.341797 17.669922 19.841797 L 17.669922 18 L 14 18 L 14 32 L 17.664062 32 C 17.664062 32 17.657969 26.766016 17.667969 24.166016 C 17.669969 23.704016 17.689203 23.23225 17.783203 22.78125 C 18.073203 21.39225 19.538031 20.534437 20.957031 20.648438 C 22.309031 20.757437 23.100016 21.495656 23.166016 23.097656 C 23.177016 23.376656 23.166016 32 23.166016 32 L 26.832031 32 L 26.832031 24.228516 C 26.838031 23.629516 26.901875 23.0175 27.046875 22.4375 C 27.372875 21.1375 28.590531 20.49825 30.019531 20.65625 C 31.279531 20.79525 32.239031 21.474609 32.332031 22.849609 L 32.332031 32 L 36 32 L 36 22 C 36 21 35.746359 20.490859 35.443359 19.880859 C 34.710859 18.405234 32.90501 17.546865 31.074219 17.509766 z"
/></svg
File diff suppressed because one or more lines are too long
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 50 50"
style=" fill:#000000;"
style="fill:currentcolor;"
><path
d="M 28 7.9453125 L 21 10.279297 L 21 18.279297 L 16 19.945312 L 10 17.945312 L 3 20.279297 L 3 29.720703 L 3.6835938 29.949219 L 9 31.720703 L 9 39.720703 L 9.6835938 39.949219 L 16 42.054688 L 23 39.720703 L 23 31.720703 L 29 29.720703 L 29 21.720703 L 34 20.054688 L 40 22.054688 L 47 19.720703 L 47 10.279297 L 40 7.9453125 L 34 9.9453125 L 28 7.9453125 z M 28 10.054688 L 32.335938 11.5 L 28 12.945312 L 23.664062 11.5 L 28 10.054688 z M 40 10.054688 L 44.335938 11.5 L 40 12.945312 L 35.664062 11.5 L 40 10.054688 z M 23 13.388672 L 27 14.720703 L 27 19.611328 L 23 18.279297 L 23 13.388672 z M 33 13.388672 L 33 18.279297 L 29 19.611328 L 29 14.720703 L 33 13.388672 z M 35 13.388672 L 39 14.720703 L 39 19.611328 L 35 18.279297 L 35 13.388672 z M 45 13.388672 L 45 18.279297 L 41 19.611328 L 41 14.720703 L 45 13.388672 z M 10 20.054688 L 14.335938 21.5 L 10 22.945312 L 5.6640625 21.5 L 10 20.054688 z M 22 20.054688 L 26.335938 21.5 L 22 22.945312 L 17.664062 21.5 L 22 20.054688 z M 5 23.388672 L 9 24.720703 L 9 29.611328 L 5 28.279297 L 5 23.388672 z M 15 23.388672 L 15 28.279297 L 11 29.611328 L 11 24.720703 L 15 23.388672 z M 17 23.388672 L 21 24.720703 L 21 29.611328 L 17 28.279297 L 17 23.388672 z M 27 23.388672 L 27 28.279297 L 23 29.611328 L 23 24.720703 L 27 23.388672 z M 16 30.054688 L 20.335938 31.5 L 16 32.945312 L 11.664062 31.5 L 16 30.054688 z M 11 33.388672 L 15 34.720703 L 15 39.611328 L 11 38.279297 L 11 33.388672 z M 21 33.388672 L 21 38.279297 L 17 39.611328 L 17 34.720703 L 21 33.388672 z"
/></svg
@@ -10,7 +10,7 @@
{width}
{height}
viewBox="0 0 30 30"
style=" fill:#000000;"
style="fill:currentcolor;"
>
<path
d="M 16.644531 2.0058594 C 16.365063 1.9841719 16.077422 2.0168281 15.794922 2.1113281 C 14.664922 2.4893281 14.053641 3.71375 14.431641 4.84375 L 15.324219 7.5117188 L 10.236328 9.2128906 L 9.3828125 6.6601562 C 9.0048125 5.5301563 7.7803906 4.9208281 6.6503906 5.2988281 C 5.5193906 5.6768281 4.9110625 6.8992969 5.2890625 8.0292969 L 6.1425781 10.582031 L 3.4746094 11.474609 C 2.3446094 11.852609 1.7333281 13.075078 2.1113281 14.205078 C 2.4893281 15.335078 3.71375 15.946359 4.84375 15.568359 L 7.5117188 14.675781 L 9.2128906 19.763672 L 6.6601562 20.617188 C 5.5301563 20.995187 4.9208281 22.219609 5.2988281 23.349609 C 5.6768281 24.480609 6.8992969 25.088938 8.0292969 24.710938 L 10.582031 23.857422 L 11.474609 26.525391 C 11.852609 27.655391 13.075078 28.266672 14.205078 27.888672 C 15.335078 27.510672 15.945359 26.28625 15.568359 25.15625 L 14.675781 22.488281 L 19.763672 20.785156 L 20.617188 23.339844 C 20.995187 24.469844 22.219609 25.079172 23.349609 24.701172 C 24.480609 24.323172 25.089891 23.100703 24.712891 21.970703 L 23.857422 19.416016 L 26.525391 18.523438 C 27.655391 18.145437 28.266672 16.922969 27.888672 15.792969 C 27.510672 14.662969 26.28625 14.053641 25.15625 14.431641 L 22.488281 15.324219 L 20.787109 10.236328 L 23.339844 9.3828125 C 24.469844 9.0048125 25.079172 7.7803906 24.701172 6.6503906 C 24.323172 5.5203906 23.100703 4.9110625 21.970703 5.2890625 L 19.417969 6.1425781 L 18.525391 3.4746094 C 18.241891 2.6271094 17.482937 2.0709219 16.644531 2.0058594 z M 16.693359 11.605469 L 18.394531 16.693359 L 13.306641 18.394531 L 11.605469 13.306641 L 16.693359 11.605469 z"
@@ -10,51 +10,13 @@
{width}
{height}
viewBox="0 0 60 60"
style=" fill:#000000;"
><linearGradient
id="2R_xNhRC2gDYhp_e6bogba"
x1="32"
x2="32"
y1="7"
y2="57"
gradientUnits="userSpaceOnUse"
><stop offset="0" stop-color="#000000" /><stop
offset="1"
stop-color="#000000"
/></linearGradient
><path
fill="url(#2R_xNhRC2gDYhp_e6bogba)"
d="M32,9c12.682,0,23,10.318,23,23S44.682,55,32,55S9,44.682,9,32S19.318,9,32,9 M32,7 C18.193,7,7,18.193,7,32s11.193,25,25,25s25-11.193,25-25S45.807,7,32,7L32,7z"
/><linearGradient
id="2R_xNhRC2gDYhp_e6bogbb"
x1="32.001"
x2="32.001"
y1="16.294"
y2="45.473"
gradientUnits="userSpaceOnUse"
><stop offset="0" stop-color="#000000" /><stop
offset="1"
stop-color="#000000"
/></linearGradient
><rect
width="3.999"
height="17.995"
x="30.001"
y="16.005"
fill="url(#2R_xNhRC2gDYhp_e6bogbb)"
/><linearGradient
id="2R_xNhRC2gDYhp_e6bogbc"
x1="32.001"
x2="32.001"
y1="16.294"
y2="45.473"
gradientUnits="userSpaceOnUse"
><stop offset="0" stop-color="#000000" /><stop
offset="1"
stop-color="#000000"
/></linearGradient
><path
fill="url(#2R_xNhRC2gDYhp_e6bogbc)"
d="M35.5,20.043v3.713c3.35,1.379,5.714,4.67,5.714,8.518c0,5.087-4.126,9.214-9.213,9.214 c-5.087,0-9.212-4.126-9.212-9.214c0-3.847,2.36-7.137,5.712-8.517v-3.714c-5.324,1.525-9.223,6.418-9.223,12.23 C19.277,39.3,24.976,45,32,45c7.026,0,12.724-5.7,12.724-12.725C44.724,26.461,40.822,21.567,35.5,20.043z"
/></svg
style="fill:currentcolor;"
>
<path
d="M32,9c12.682,0,23,10.318,23,23S44.682,55,32,55S9,44.682,9,32S19.318,9,32,9 M32,7 C18.193,7,7,18.193,7,32s11.193,25,25,25s25-11.193,25-25S45.807,7,32,7L32,7z"
/>
<rect width="3.999" height="17.995" x="30.001" y="16.005" />
<path
d="M35.5,20.043v3.713c3.35,1.379,5.714,4.67,5.714,8.518c0,5.087-4.126,9.214-9.213,9.214 c-5.087,0-9.212-4.126-9.212-9.214c0-3.847,2.36-7.137,5.712-8.517v-3.714c-5.324,1.525-9.223,6.418-9.223,12.23 C19.277,39.3,24.976,45,32,45c7.026,0,12.724-5.7,12.724-12.725C44.724,26.461,40.822,21.567,35.5,20.043z"
/>
</svg>
@@ -41,17 +41,13 @@
{#if keys.length > 0}
<span class:hidden={collapsed}>
{#if level != 0}<span
class="cursor-pointer hover:bg-slate-200 px-1 rounded"
on:click={collapse}
>
(-)
</span>
{#if level != 0}
<span class="cursor-pointer hover:bg-gray-200 px-1 rounded" on:click={collapse}> (-) </span>
{/if}
<ul class="w-full">
{#each keys as key, index}
<li class="pt-1">
<button on:click={() => selectProp(key)} class="key rounded px-1 hover:bg-sky-100">
<button on:click={() => selectProp(key)} class="key rounded px-1 hover:bg-blue-100">
{!isArray ? key : index}:
</button>
@@ -66,7 +62,7 @@
/>
{:else}
<button
class="val rounded px-1 hover:bg-sky-100 {getTypeAsString(json[key])}"
class="val rounded px-1 hover:bg-blue-100 {getTypeAsString(json[key])}"
on:click={() => selectProp(key)}
>
{#if json[key] === NEVER_TESTED_THIS_FAR}
@@ -82,7 +78,7 @@
{/each}
</ul>
</span>
<span class="cursor-pointer hover:bg-slate-200" class:hidden={!collapsed} on:click={collapse}>
<span class="cursor-pointer hover:bg-gray-200" class:hidden={!collapsed} on:click={collapse}>
{openBracket}{collapsedSymbol}{closeBracket}
</span>
{#if !isLast && collapsed}
@@ -111,12 +107,12 @@
@apply text-red-500;
}
.val.string {
@apply text-lime-600;
@apply text-green-600;
}
.val.number {
@apply text-orange-600;
}
.val.boolean {
@apply text-cyan-600;
@apply text-blue-600;
}
</style>
+23 -35
View File
@@ -36,6 +36,7 @@
import TableCustom from '$lib/components/TableCustom.svelte'
import Modal from '$lib/components/Modal.svelte'
import FlowViewer from '$lib/components/FlowViewer.svelte'
import { Button } from '../lib/components/common'
type Tab = 'all' | 'personal' | 'groups' | 'shared' | 'hub'
type Section = [string, FlowW[]]
@@ -160,9 +161,7 @@
<CenteredPage>
<PageHeader title="Flows" tooltip="Flows can compose and chain scripts together">
<div class="flex flex-row">
<a class="default-button" href="/flows/add"
><Icon class="text-white mb-1" data={faPlus} scale={0.9} /> &nbsp; New flow</a
>
<Button href="/flows/add" size="sm" startIcon={{ icon: faPlus }}>New flow</Button>
</div>
</PageHeader>
@@ -259,7 +258,9 @@
<div class="grid md:grid-cols-2 gap-4 sm:grid-cols-1 xl:grid-cols-3">
{#each flows as { summary, path, extra_perms, canWrite }}
<div
class="flex flex-col justify-between flow max-w-lg overflow-visible shadow-sm shadow-blue-100 border border-gray-200 bg-gray-50 py-2"
class="flex flex-col justify-between max-w-lg overflow-visible
shadow-sm shadow-blue-100 border border-gray-200
hover:border hover:border-gray-600 hover:border-opacity-60 bg-gray-50 py-2"
>
<a href="/flows/get/{path}">
<div class="px-6 overflow-auto ">
@@ -327,40 +328,37 @@
</div>
{#if canWrite}
<div>
<a
class="inline-flex items-center default-button bg-transparent hover:bg-blue-500 text-blue-700 font-normal hover:text-white py-0 px-1 border-blue-500 hover:border-transparent rounded"
<Button
variant="border"
size="xs"
href="/flows/edit/{path}"
endIcon={{ icon: faEdit }}
>
<div class="inline-flex items-center justify-center px-4">
<Icon data={faEdit} scale={0.6} />
<span class="pl-1">Edit</span>
</div>
</a>
Edit
</Button>
</div>
{:else}
<div>
<a
class="inline-flex items-center default-button bg-transparent hover:bg-blue-500 text-blue-700 font-normal hover:text-white py-0 px-1 border-blue-500 hover:border-transparent rounded"
<Button
variant="border"
size="xs"
href="/flows/add?template={path}"
endIcon={{ icon: faCodeFork }}
>
<div class="inline-flex items-center justify-center px-4">
<Icon data={faCodeFork} scale={0.6} />
<span class="pl-1">Fork</span>
</div>
</a>
Fork
</Button>
</div>
{/if}
<div>
<a
class="inline-flex items-center default-button bg-transparent hover:bg-blue-500 text-blue-700 font-normal hover:text-white py-0 px-1 border-blue-500 hover:border-transparent rounded"
<Button
variant="border"
size="xs"
href="/flows/run/{path}"
endIcon={{ icon: faPlay }}
>
<div class="inline-flex items-center justify-center px-4">
<Icon data={faPlay} scale={0.6} />
<span class="pl-1">Run</span>
</div>
</a>
Run
</Button>
</div>
</div>
</div>
@@ -381,13 +379,3 @@
loadFlows()
}}
/>
<style>
.selected:hover {
@apply border border-gray-500 rounded-md border-opacity-50;
}
.flow:hover {
@apply border border-gray-600 border-opacity-60;
}
</style>
+5 -6
View File
@@ -22,6 +22,7 @@
import { faEdit, faPlus, faShare } from '@fortawesome/free-solid-svg-icons'
import { Alert } from 'flowbite-svelte'
import Icon from 'svelte-awesome'
import { Button } from '$lib/components/common'
type GroupW = Group & { canWrite: boolean }
@@ -74,14 +75,12 @@
<input
class="mr-2"
on:keyup={handleKeyUp}
placeholder="new group name"
placeholder="New group name"
bind:value={newGroupName}
/>
<button
class={newGroupName ? 'default-button' : 'default-button-disabled'}
on:click={addGroup}
><Icon class="text-white mb-1" data={faPlus} scale={0.9} /> &nbsp; New group</button
>
<Button size="sm" startIcon={{ icon: faPlus }} disabled={!newGroupName} on:click={addGroup}>
New&nbsp;group
</Button>
</div>
</PageHeader>
+26 -38
View File
@@ -12,7 +12,6 @@
import type { Resource, ResourceType } from '$lib/gen'
import PageHeader from '$lib/components/PageHeader.svelte'
import ResourceEditor from '$lib/components/ResourceEditor.svelte'
import Button from '$lib/components/Button.svelte'
import TableCustom from '$lib/components/TableCustom.svelte'
import Modal from '$lib/components/Modal.svelte'
import Highlight from 'svelte-highlight'
@@ -39,8 +38,8 @@
import Required from '$lib/components/Required.svelte'
import AppConnect from '$lib/components/AppConnect.svelte'
import { page } from '$app/stores'
import { onMount } from 'svelte'
import { Button } from '$lib/components/common'
import ConfirmationModal from '$lib/components/common/confirmationModal/ConfirmationModal.svelte'
import Alert from '$lib/components/common/alert/Alert.svelte'
import Badge from '$lib/components/common/badge/Badge.svelte'
@@ -125,6 +124,15 @@
}
}
const startNewType = () => {
resourceViewerTitle = `Create resource type`
newResourceTypeName = 'my_resource_type'
newResourceTypeSchema = emptySchema()
newResourceTypeDescription = 'my description'
typeModalMode = 'create'
resourceViewer.openModal()
}
$: {
if ($workspaceStore && $userStore) {
loadResources()
@@ -146,18 +154,12 @@
<CenteredPage>
<PageHeader title="Resources">
<div class="flex flex-row space-x-4">
<button
class="default-button"
on:click={() => {
appConnect.open()
}}><Icon class="text-white mb-1" data={faChain} scale={0.9} /> &nbsp; Connect an API</button
>
<button
class="default-button"
on:click={() => {
resourceEditor?.initNew()
}}><Icon class="text-white mb-1" data={faPlus} scale={0.9} /> &nbsp; Add a resource</button
>
<Button size="sm" startIcon={{ icon: faChain }} on:click={() => appConnect.open()}>
Connect an API
</Button>
<Button size="sm" startIcon={{ icon: faPlus }} on:click={() => resourceEditor?.initNew()}>
Add a resource
</Button>
</div>
</PageHeader>
@@ -253,18 +255,7 @@
</div>
<div class="py-10" />
<PageHeader title="Resources types" primary={false}>
<button
class="default-button"
on:click={() => {
resourceViewerTitle = `Create resource type`
newResourceTypeName = 'my_resource_type'
newResourceTypeSchema = emptySchema()
newResourceTypeDescription = 'my description'
typeModalMode = 'create'
resourceViewer.openModal()
}}><Icon class="text-white mb-1" data={faPlus} scale={0.9} /> &nbsp; Add a type</button
>
<Button size="sm" startIcon={{ icon: faPlus }} on:click={startNewType}>Add a type</Button>
</PageHeader>
<TableCustom>
@@ -292,13 +283,14 @@
<td>
{#if canWrite}
<Button
category="delete"
class="mx-2"
on:click={() => {
handleDeleteResourceType(name)
}}
disabled={!($userStore?.is_admin ?? false)}
/>
size="sm"
color="red"
startIcon={{ icon: faTrash }}
on:click={() => handleDeleteResourceType(name)}
disabled={!($userStore?.is_admin || false)}
>
Delete
</Button>
{/if}
</td>
</tr>
@@ -343,8 +335,6 @@
><h3 class="mt-4 font-semibold text-gray-700">Description</h3>
<input type="text" bind:value={newResourceTypeDescription} /></label
>
<!-- svelte-ignore a11y-label-has-associated-control -->
<!-- <label>Schema <AutosizedTextarea minRows={10} bind:value={newResourceTypeSchema} /></label> -->
<h3 class="mt-4 mb-2 font-semibold text-gray-700">Schema</h3>
<SchemaEditor bind:schema={newResourceTypeSchema} />
{:else if typeModalMode === 'view'}
@@ -355,9 +345,7 @@
</div>
<div slot="submission">
{#if typeModalMode === 'create'}
<button class="default-button px-4 py-2 font-semibold" on:click={addResourceType}>
Save
</button>
<Button on:click={addResourceType}>Save</Button>
{/if}
</div>
</Modal>
+76 -43
View File
@@ -48,6 +48,7 @@
import HighlightCode from '$lib/components/HighlightCode.svelte'
import TestJobLoader from '$lib/components/TestJobLoader.svelte'
import LogViewer from '$lib/components/LogViewer.svelte'
import { Button } from '$lib/components/common'
let workspace_id_query: string | undefined = $page.url.searchParams.get('workspace') ?? undefined
let workspace_id: string | undefined
@@ -108,7 +109,7 @@
/>
<CenteredPage>
<div class="flex flex-row flex-wrap justify-between">
<div class="flex flex-row flex-wrap justify-between items-center gap-4 pb-4">
<h1>
<div>
{#if job}
@@ -172,87 +173,119 @@
{/if}
</div>
</h1>
<div>
<div class="flex flex-wrap gap-2">
{#if job && 'deleted' in job && !job?.deleted && ($userStore?.is_admin ?? false)}
<button
class="default-button-secondary bg-transparent hover:bg-red-500 text-red-700 border-red-500 hover:text-white hover:border-transparent py-1"
<Button
variant="border"
color="red"
size="sm"
startIcon={{ icon: faTrash }}
on:click={() => {
if (job?.id) {
deleteCompletedJob(job?.id)
}
}}
>
<div class="text-red-500 hover:text-white text-sm">
<Icon class="" data={faTrash} scale={0.5} />
<span class="pl-1">Delete</span>
</div>
</button>
Delete
</Button>
{/if}
{#if job && 'running' in job && job.running}
<button
class="default-button-secondary bg-transparent hover:bg-red-500 text-red-700 border-red-500 hover:text-white hover:border-transparent"
<Button
variant="border"
color="red"
size="sm"
startIcon={{ icon: faTimesCircle }}
on:click|once={() => {
if (job?.id) {
cancelJob(job?.id)
}
}}
>
<div
class="inline-flex items-center justify-center text-red-500 hover:text-white text-sm"
>
<Icon class="" data={faTimesCircle} scale={0.5} />
<span class="pl-1">Cancel</span>
</div>
</button>
Cancel
</Button>
{/if}
{#if job?.job_kind == 'script'}
{#if canWrite(job?.script_path ?? '', {}, $userStore)}
<a
<Button
href="/scripts/edit/{job?.script_hash}?step=2"
class="default-button-secondary py-1 text-sm px-2"
><Icon data={faEdit} scale={0.6} /><span class="px-1">Edit</span></a
variant="border"
color="blue"
size="sm"
startIcon={{ icon: faEdit }}
>
Edit
</Button>
{/if}
<a href="/scripts/get/{job?.script_hash}" class="default-button-secondary py-1 text-sm px-2"
><Icon data={faScroll} scale={0.6} /><span class="px-1">View script</span></a
<Button
href="/scripts/get/{job?.script_hash}"
variant="border"
color="blue"
size="sm"
startIcon={{ icon: faScroll }}
>
<a href="/runs/{job?.script_path}" class="default-button-secondary py-1 text-sm px-2"
><Icon data={faList} scale={0.6} /><span class="px-1">View runs</span></a
View script
</Button>
<Button
href="/runs/{job?.script_path}"
variant="border"
color="blue"
size="sm"
startIcon={{ icon: faList }}
>
<a
View runs
</Button>
<Button
href="/scripts/run/{job?.script_hash}{job?.args
? `?args=${encodeURIComponent(encodeState(job?.args))}`
: ''}"
class="default-button-secondary py-1 text-sm px-2"
><Icon class="text-yellow-400" data={faBolt} scale={0.6} label="Run again" /><span
class="px-1">Run again</span
></a
variant="border"
color="blue"
size="sm"
startIcon={{ icon: faBolt }}
>
Run again
</Button>
{:else if job?.job_kind == 'flow'}
{#if canWrite(job?.script_path ?? '', {}, $userStore)}
<a
<Button
href="/flows/edit/{job?.script_path}"
class="default-button-secondary py-1 text-sm px-2"
><Icon data={faEdit} scale={0.6} /><span class="px-1">Edit</span></a
variant="border"
color="blue"
size="sm"
startIcon={{ icon: faEdit }}
>
Edit
</Button>
{/if}
<a href="/flows/get/{job?.script_path}" class="default-button-secondary py-1 text-sm px-2"
><Icon data={faScroll} scale={0.6} /><span class="px-1">View flow</span></a
<Button
href="/flows/get/{job?.script_path}"
variant="border"
color="blue"
size="sm"
startIcon={{ icon: faScroll }}
>
<a
View flow
</Button>
<Button
href="/runs/{job?.script_path}?jobKind=flow"
class="default-button-secondary py-1 text-sm px-2"
><Icon data={faList} scale={0.6} /><span class="px-1">View runs</span></a
variant="border"
color="blue"
size="sm"
startIcon={{ icon: faList }}
>
<a
View runs
</Button>
<Button
href="/flows/run/{job?.script_path}{job?.args
? `?args=${encodeURIComponent(encodeState(job?.args))}`
: ''}"
class="default-button-secondary py-1 text-sm px-2"
><Icon class="text-yellow-400" data={faBolt} scale={0.6} label="Run again" /><span
class="px-1">Run again</span
></a
variant="border"
color="blue"
size="sm"
startIcon={{ icon: faBolt }}
>
Run again
</Button>
{/if}
</div>
</div>
+3 -9
View File
@@ -10,10 +10,9 @@
import { page } from '$app/stores'
import { sendUserToast, formatCron } from '$lib/utils'
import { ScriptService, Script, ScheduleService, type Flow, FlowService } from '$lib/gen'
import PageHeader from '$lib/components/PageHeader.svelte'
import Path from '$lib/components/Path.svelte'
import { Button } from '$lib/components/common'
import Tooltip from '$lib/components/Tooltip.svelte'
import { goto } from '$app/navigation'
import { workspaceStore } from '$lib/stores'
@@ -167,14 +166,9 @@
<CronInput bind:schedule bind:validCRON />
<div class="flex flex-row-reverse mt-2 ">
<div>
<button
type="submit"
disabled={!allowSchedule || pathError != ''}
class="default-button w-min px-6"
on:click={scheduleScript}
>
<Button disabled={!allowSchedule || pathError != ''} on:click={scheduleScript}>
{edit ? 'Save' : 'Schedule'}
</button>
</Button>
</div>
</div>
</div>
+3 -4
View File
@@ -28,6 +28,7 @@
import CenteredPage from '$lib/components/CenteredPage.svelte'
import Icon from 'svelte-awesome'
import Toggle from '$lib/components/Toggle.svelte'
import { Button } from '$lib/components/common'
type ScheduleW = Schedule & { canWrite: boolean }
@@ -62,10 +63,8 @@
</script>
<CenteredPage>
<PageHeader title="Schedules">
<button class="default-button" on:click={() => goto('/schedule/add')}
><Icon class="text-white mb-1" data={faPlus} scale={0.9} /> &nbsp; New schedule</button
>
<PageHeader title="Schedule">
<Button size="sm" startIcon={{ icon: faPlus }} href="/schedule/add">New&nbsp;schedule</Button>
</PageHeader>
<div class="relative mt-10">
<TableCustom>
+27 -28
View File
@@ -43,6 +43,7 @@
import TableCustom from '$lib/components/TableCustom.svelte'
import { Highlight } from 'svelte-highlight'
import { typescript } from 'svelte-highlight/languages/typescript'
import { Button } from '$lib/components/common'
type Tab = 'all' | 'personal' | 'groups' | 'shared' | 'examples' | 'hub'
type Section = [string, ScriptW[]]
@@ -186,17 +187,18 @@
granted visibility on the resources and variables it uses, otherwise it will behave as if those
items did not exist at runtime of the script."
>
<div class="flex flex-row">
<button
class="default-button-secondary border-none"
<div class="flex flex-row gap-2">
<Button
variant="border"
size="sm"
startIcon={{ icon: faPlus }}
on:click={() => {
templateModal.openModal()
}}
><Icon class="text-blue-500 mb-1" data={faPlus} scale={0.9} /> New script from template</button
>
<a class="default-button" href="/scripts/add"
><Icon class="text-white mb-1" data={faPlus} scale={0.9} /> &nbsp; New script</a
>
New script from template
</Button>
<Button size="sm" startIcon={{ icon: faPlus }} href="/scripts/add">New script</Button>
</div>
</PageHeader>
@@ -392,39 +394,36 @@
</div>
{#if canWrite}
<div>
<a
class="inline-flex items-center default-button bg-transparent hover:bg-blue-500 text-blue-700 font-normal hover:text-white py-0 px-1 border-blue-500 hover:border-transparent rounded"
<Button
variant="border"
size="xs"
startIcon={{ icon: faEdit }}
href="/scripts/edit/{hash}?step=2"
>
<div class="inline-flex items-center justify-center px-4">
<Icon data={faEdit} scale={0.6} />
<span class="pl-1">Edit</span>
</div>
</a>
Edit
</Button>
</div>
{:else}
<div>
<a
class="inline-flex items-center default-button bg-transparent hover:bg-blue-500 text-blue-700 font-normal hover:text-white py-0 px-1 border-blue-500 hover:border-transparent rounded"
<Button
variant="border"
size="xs"
startIcon={{ icon: faCodeFork }}
href="/scripts/add?template={path}"
>
<div class="inline-flex items-center justify-center px-4">
<Icon data={faCodeFork} scale={0.6} />
<span class="pl-1">Fork</span>
</div>
</a>
Fork
</Button>
</div>
{/if}
<div>
<a
class="inline-flex items-center default-button bg-transparent hover:bg-blue-500 text-blue-700 font-normal hover:text-white py-0 px-1 border-blue-500 hover:border-transparent rounded"
<Button
variant="border"
size="xs"
startIcon={{ icon: faPlay }}
href="/scripts/run/{hash}"
>
<div class="inline-flex items-center justify-between px-4">
<Icon data={faPlay} scale={0.6} />
<span class="pl-1">Run</span>
</div>
</a>
Run
</Button>
</div>
</div>
</div>
@@ -31,7 +31,6 @@
faCodeFork,
faClipboard
} from '@fortawesome/free-solid-svg-icons'
import Tooltip from '$lib/components/Tooltip.svelte'
import ShareModal from '$lib/components/ShareModal.svelte'
import { userStore, workspaceStore } from '$lib/stores'
@@ -322,7 +321,7 @@
<div class="flex flex-col lg:flex-row gap-4">
<div class="lg:w-1/2">
<h3 class="text-lg mb-1 font-bold text-gray-600">Webhooks</h3>
<div class="border rounded-sm shadow-sm p-4">
<div class="box">
<Tabs selected="uuid">
<Tab value="uuid">UUID</Tab>
<Tab value="result">Result</Tab>
@@ -364,7 +363,7 @@
</div>
<div class="lg:w-1/2">
<h3 class="text-lg mb-1 font-bold text-gray-600">Versions</h3>
<div class="border rounded-sm shadow-sm p-4">
<div class="box">
<h4 class="font-bold text-gray-500">Current</h4>
<div class="mt-1">
{script?.hash}
@@ -64,7 +64,7 @@
<input
on:keyup={handleKey}
bind:value={username}
class="default-input"
class="mt-1"
class:input-error={errorUsername != ''}
/>
</label>
@@ -1,13 +1,12 @@
<script lang="ts">
import { goto } from '$app/navigation'
import { UserService, WorkspaceService } from '$lib/gen'
import { sendUserToast, validateUsername } from '$lib/utils'
import { logoutWithRedirect } from '$lib/logout'
import { page } from '$app/stores'
import { usersWorkspaceStore, workspaceStore } from '$lib/stores'
import CenteredModal from '$lib/components/CenteredModal.svelte'
import { Button } from '$lib/components/common'
const rd = $page.url.searchParams.get('rd')
@@ -93,31 +92,29 @@
<label class="block pb-2">
<span class="text-gray-700">workspace name:</span>
<input bind:value={name} class="default-input" />
<input bind:value={name} class="mt-1" />
</label>
<label class="block pb-2">
<span class="text-gray-700">workspace id:</span>
{#if errorId}
<span class="text-red-500 text-xs">{errorId}</span>
{/if}
<input bind:value={id} class="default-input" class:input-error={errorId != ''} />
<input bind:value={id} class="mt-1" class:input-error={errorId != ''} />
</label>
<label class="block pb-2">
<span class="text-gray-700">your username in that workspace:</span>
{#if errorUser}
<span class="text-red-500 text-xs">{errorUser}</span>
{/if}
<input bind:value={username} on:keyup={handleKeyUp} class="default-input" />
<input bind:value={username} on:keyup={handleKeyUp} class="mt-1" />
</label>
<div class="flex flex-row justify-between pt-4">
<a href="/user/workspaces">&leftarrow; Back to workspaces</a>
<button
<Button
disabled={errorId != '' || errorUser != '' || !name || !username || !id}
class="default-button"
type="button"
on:click={createWorkspace}
>
Create workspace
</button>
</Button>
</div>
</CenteredModal>
+37 -31
View File
@@ -18,11 +18,29 @@
import { sendUserToast } from '$lib/utils'
import CenteredModal from '$lib/components/CenteredModal.svelte'
import { getUserExt, refreshSuperadmin } from '$lib/user'
import { Button } from '$lib/components/common'
let email = $page.url.searchParams.get('email') ?? ''
let password = $page.url.searchParams.get('password') ?? ''
const error = $page.url.searchParams.get('error') ?? undefined
const rd = $page.url.searchParams.get('rd')
const providers = [
{
type: 'github',
name: 'Github',
icon: faGithub
},
{
type: 'gitlab',
name: 'Gitlab',
icon: faGitlab
},
{
type: 'google',
name: 'Google',
icon: faGoogle
}
] as const
let showPassword = false
let logins: string[] = []
@@ -79,10 +97,11 @@
}
}
function storeRedirect() {
function storeRedirect(provider: typeof providers[number]['type']) {
if (rd) {
localStorage.setItem('rd', rd)
}
goto('/api/oauth/login/' + provider)
}
if (error) {
@@ -94,32 +113,19 @@
<!-- Enable submit form on enter -->
<CenteredModal>
<div class="justify-center text-center flex flex-col">
{#if logins.includes('github')}
<a on:click={storeRedirect} rel="external" href="/api/oauth/login/github"
><button class="m-auto default-button bg-black mt-2 py-2 w-full text-gray-200"
>Github &nbsp;
<Icon class="text-white pb-1" data={faGithub} scale={1.4} />
</button></a
>
{/if}
{#if logins.includes('gitlab')}
<a on:click={storeRedirect} rel="external" href="/api/oauth/login/gitlab"
><button
class="m-auto default-button bg-orange-400 mt-2 py-2 w-full text-black hover:bg-orange-600"
>Gitlab &nbsp;
<Icon class="pb-1" data={faGitlab} scale={1.4} />
</button></a
>
{/if}
{#if logins.includes('google')}
<a on:click={storeRedirect} rel="external" href="/api/oauth/login/google"
><button
class="m-auto default-button bg-gray-100 mt-2 py-2 w-full text-black hover:bg-blue-300"
>Google &nbsp;
<Icon class="pb-1" data={faGoogle} scale={1.4} />
</button></a
>
{/if}
{#each providers as { type, icon, name }}
{#if logins.includes(type)}
<Button
color="dark"
variant="border"
endIcon={{ icon }}
btnClasses="mt-2"
on:click={() => storeRedirect(type)}
>
{name}
</Button>
{/if}
{/each}
</div>
<div class="flex flex-row-reverse w-full">
<button
@@ -139,7 +145,7 @@
</p>
<label class="block pb-2">
<span class="text-gray-700">email</span>
<input bind:value={email} class="default-input" id="email" />
<input bind:value={email} class="mt-1" id="email" />
</label>
<label class="block ">
<span class="text-gray-700">password</span>
@@ -147,12 +153,12 @@
type="password"
on:keyup={handleKeyUp}
bind:value={password}
class="default-input"
class="mt-1"
id="password"
/>
</label>
<div class="flex flex-row-reverse pt-4">
<button id="login2" class="default-button" type="button" on:click={login}> Login </button>
<div class="flex justify-end pt-4">
<Button id="login2" on:click={login}>Login</Button>
</div>
</div>
{/if}
+16 -10
View File
@@ -8,6 +8,7 @@
import { faPlus } from '@fortawesome/free-solid-svg-icons'
import TableCustom from '$lib/components/TableCustom.svelte'
import CenteredModal from '$lib/components/CenteredModal.svelte'
import { Button } from '$lib/components/common'
let newPassword: string | undefined
let passwordError: string | undefined
@@ -77,7 +78,7 @@
<h2 class="border-b">User info</h2>
<div class="">
{#if passwordError}
<div class="text-purple-500 text-2xs grow">{passwordError}</div>
<div class="text-red-600 text-2xs grow">{passwordError}</div>
{/if}
<div class="flex flex-col gap-2 w-full ">
<div class="mt-4">
@@ -104,7 +105,7 @@
text-sm
"
/>
<button on:click={() => setPassword()} class="mt-4 default-button">Set password</button>
<Button size="sm" btnClasses="mt-4" on:click={setPassword}>Set password</Button>
</label>
{:else if login_type == 'github'}
<span>Authentified through Github OAuth2. Cannot set a password.</span>
@@ -115,21 +116,24 @@
<div class="grid grid-cols-2 pt-24 pb-1">
<h2 class="py-0 my-0 border-b">Tokens</h2>
<div class="text-right py-0 my-0 border-b">
<button
<div class="flex justify-end border-b pb-1">
<Button
size="xs"
startIcon={{ icon: faPlus }}
btnClasses={displayCreateToken ? 'hidden' : ''}
on:click={() => {
displayCreateToken = !displayCreateToken
newToken = undefined
newTokenExpiration = undefined
newTokenLabel = undefined
}}
class="default-button py-0 {displayCreateToken ? 'hidden' : ''}"
><Icon class="text-white mb-1" data={faPlus} scale={0.9} /> &nbsp; Create token</button
>
Create token
</Button>
</div>
</div>
<div class="text-2xs text-gray-500 italic pb-6">
Authentify to the windmill API with access tokens.
Authentify to the Windmill API with access tokens.
</div>
<div>
@@ -176,9 +180,11 @@
getToday().getDate()}
/>
</div>
<label class="block md:w-1/2">Label (optional)<input bind:value={newTokenLabel} /></label>
<div class="flex flex-col-reverse">
<button class="default-button" on:click={createToken}>Submit</button>
<label class="flex flex-col justify-end md:w-1/2"
>Label (optional)<input bind:value={newTokenLabel} /></label
>
<div class="flex items-end">
<Button size="sm" btnClasses="!mt-2" on:click={createToken}>Submit</Button>
</div>
</div>
</div>
@@ -18,6 +18,7 @@
import Switch from '$lib/components/Switch.svelte'
import { faCrown, faUserCog } from '@fortawesome/free-solid-svg-icons'
import Icon from 'svelte-awesome'
import { Button } from '$lib/components/common'
let invites: WorkspaceInvite[] = []
let list_all_as_super_admin: boolean = false
@@ -177,13 +178,15 @@
<a class="mr-10" href="/user/settings">
<Icon data={faUserCog} class="mr-1" scale={1} />User settings</a
>
<button
class="default-button-secondary"
<Button
variant="border"
color="blue"
size="sm"
on:click={async () => {
logout()
}}
>
logout
</button>
</Button>
</div>
</CenteredModal>
+4 -8
View File
@@ -21,6 +21,7 @@
import CenteredPage from '$lib/components/CenteredPage.svelte'
import Icon from 'svelte-awesome'
import { faPlus, faCircle } from '@fortawesome/free-solid-svg-icons'
import { Button } from '$lib/components/common'
import ConfirmationModal from '$lib/components/common/confirmationModal/ConfirmationModal.svelte'
import Alert from '$lib/components/common/alert/Alert.svelte'
import Badge from '$lib/components/common/badge/Badge.svelte'
@@ -70,14 +71,9 @@
<CenteredPage>
<PageHeader title="Variables">
<button
class="default-button"
on:click={() => {
variableEditor.initNew()
}}
>
<Icon class="text-white mb-1" data={faPlus} scale={0.9} /> &nbsp; New variable</button
>
<Button size="sm" startIcon={{ icon: faPlus }} on:click={() => variableEditor.initNew()}>
New&nbsp;variable
</Button>
</PageHeader>
<VariableEditor bind:this={variableEditor} on:create={loadVariables} />
+25 -15
View File
@@ -28,6 +28,7 @@
import ScriptPicker from '$lib/components/ScriptPicker.svelte'
import AppConnect from '$lib/components/AppConnect.svelte'
import { onMount } from 'svelte'
import { Button } from '$lib/components/common'
let users: User[] = []
let invites: WorkspaceInvite[] = []
@@ -205,21 +206,26 @@
<p class="text-xs text-gray-700 my-1">
Status: {#if team_name}Connected to slack workspace {team_name}{:else}Not connected{/if}
</p>
<a class="default-button mt-2" rel="external" href="/api/oauth/connect_slack"
>Connect to slack <Icon class="text-white mb-1" data={faSlack} scale={0.9} />
</a>
<div class="flex justify-start">
<Button size="sm" endIcon={{ icon: faSlack }} href="/api/oauth/connect_slack">
Connect to Slack
</Button>
</div>
{#if team_name}
<button
class="default-button mt-2"
<Button
size="sm"
endIcon={{ icon: faSlack }}
btnClasses="mt-2"
on:click={async () => {
await OauthService.disconnectSlack({
workspace: $workspaceStore ?? ''
})
loadSlack()
sendUserToast('Disconnected slack')
sendUserToast('Disconnected Slack')
}}
>Disconnect slack <Icon class="text-white mb-1" data={faSlack} scale={0.9} />
</button>
>
Disconnect Slack
</Button>
{/if}
<h3 class="mt-5 text-gray-700">Select a script to run on /windmill command:</h3>
<ScriptPicker kind={Script.kind.SCRIPT} bind:scriptPath on:select={editSlackCommand} />
@@ -235,18 +241,21 @@
</p>
<div class="mt-10" />
<PageHeader title="Export workspace" primary={false} />
<a
class="default-button"
target="_blank"
href="/api/w/{$workspaceStore ?? ''}/workspaces/tarball">Export workspace as tarball</a
>
<div class="flex justify-start">
<Button size="sm" href="/api/w/{$workspaceStore ?? ''}/workspaces/tarball" target="_blank">
Export workspace as tarball
</Button>
</div>
<div class="mt-20" />
<PageHeader title="Delete workspace" primary={false} />
<p class="italic text-xs">
The workspace will be archived for a short period of time and then permanently deleted
</p>
<button
<Button
color="red"
size="sm"
btnClasses="mt-2"
on:click={async () => {
await WorkspaceService.deleteWorkspace({ workspace: $workspaceStore ?? '' })
sendUserToast(`Successfully deleted workspace ${$workspaceStore}`)
@@ -254,8 +263,9 @@
usersWorkspaceStore.set(undefined)
goto('/user/workspaces')
}}
class="default-button mt-2 bg-red-500">Delete workspace</button
>
Delete workspace
</Button>
{:else}
<div class="bg-red-100 border-l-4 border-red-600 text-orange-700 p-4 m-4" role="alert">
<p class="font-bold">Not an admin</p>
+204 -2
View File
@@ -1,10 +1,95 @@
const plugin = require('tailwindcss/plugin');
/** @type {import('tailwindcss').Config} */
const config = {
content: [
'./src/**/*.{html,js,svelte,ts}',
"./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}",
],
safelist: [
'inline-highlight'
],
theme: {
colors: {
current: 'currentcolor',
transparent: 'transparent',
white: '#ffffff',
gray: {
50: '#f9fafb',
100: '#f3f4f6',
200: '#e5e7eb',
300: '#d1d5db',
400: '#9ca3af',
500: '#6b7280',
600: '#4b5563',
700: '#374151',
800: '#1f2937',
900: '#111827',
},
red: {
50: '#fef2f2',
100: '#fee2e2',
200: '#fecaca',
300: '#fca5a5',
400: '#f87171',
500: '#ef4444',
600: '#dc2626',
700: '#b91c1c',
800: '#991b1b',
900: '#7f1d1d',
},
orange: {
100: '#ffedd5',
400: '#fb923c',
500: '#f97316',
600: '#ea580c',
700: '#c2410c',
},
yellow: {
50: '#fefce8',
100: '#fef9c3',
200: '#fef08a',
300: '#fde047',
400: '#facc15',
500: '#eab308',
600: '#ca8a04',
700: '#a16207',
800: '#854d0e',
900: '#713f12',
},
green: {
50: '#f0fdf4',
100: '#dcfce7',
200: '#bbf7d0',
300: '#86efac',
400: '#4ade80',
500: '#22c55e',
600: '#16a34a',
700: '#15803d',
800: '#166534',
900: '#14532d',
},
blue: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
},
indigo: {
100: '#e0e7ff',
200: '#c7d2fe',
300: '#a5b4fc',
500: '#6366f1',
800: '#3730a3',
900: '#312e81',
}
},
extend: {
maxHeight: {
'1/2': '50vh',
@@ -27,6 +112,9 @@ const config = {
},
transitionProperty: {
'height': 'height'
},
fontSize: {
'2xs': '0.7rem'
}
}
},
@@ -34,7 +122,121 @@ const config = {
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
require('flowbite/plugin')
require('flowbite/plugin'),
plugin(({ addBase, addComponents, addUtilities, theme }) => {
addBase({
'html': {
overflowY: 'auto'
},
'h1': {
fontSize: theme('fontSize.2xl'),
color: theme('colors.gray.700')
},
'h1': {
fontSize: theme('fontSize.xl'),
color: theme('colors.blue.500')
},
'a': {
color: theme('colors.blue.500')
},
'input,input[type="text"],input[type="email"],input[type="url"],input[type="password"],input[type="number"],input[type="date"],input[type="datetime-local"],input[type="month"],input[type="search"],input[type="tel"],input[type="time"],input[type="week"],textarea,select': {
display: 'block',
fontSize: theme('fontSize.sm'),
width: '100%',
padding: `${theme('spacing.1')} ${theme('spacing.2')}`,
border: `1px solid ${theme('colors.gray.300')}`,
borderRadius: theme('borderRadius.md'),
boxShadow: theme('boxShadow.sm'),
'&:focus': {
'--tw-ring-color': theme('colors.indigo.100'),
'--tw-ring-offset-shadow': 'var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)',
'--tw-ring-shadow': 'var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color)',
boxShadow: 'var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)'
},
'&:disabled,[disabled]': {
backgroundColor: theme('colors.gray.100') + ' !important'
}
},
'button:disabled,button[disabled=true],a:disabled,a[disabled=true]': {
pointerEvents: 'none',
cursor: 'default',
filter: 'grayscale(1)'
}
});
addComponents({
'#table-custom': {
'& th': {
paddingTop: theme('spacing.3'),
paddingBottom: theme('spacing.3'),
fontSize: theme('fontSize.sm'),
textAlign: 'left',
fontWeight: theme('fontWeight.semibold'),
color: theme('colors.gray.900'),
textTransform: 'capitalize',
},
'& td': {
paddingTop: theme('spacing.4'),
paddingBottom: theme('spacing.4'),
fontSize: theme('fontSize.sm'),
color: theme('colors.gray.700'),
},
'& tbody > :not([hidden]) ~ :not([hidden])': {
borderTop: `1px solid ${theme('colors.gray.200')}`
},
},
'.commit-hash': {
fontSize: theme('fontSize.2xs'),
color: theme('colors.gray.500'),
backgroundColor: theme('colors.gray.200'),
fontFamily: theme('fontFamily.mono'),
},
'.input-error': {
borderColor: `${theme('colors.red.500')} !important`
},
'.box': {
borderWidth: '1px',
borderRadius: theme('borderRadius.sm'),
boxShadow: theme('boxShadow.sm'),
padding: theme('spacing.4')
},
'.inline-highlight': {
'& pre code.hljs': {
padding: '0px',
fontSize: theme('fontSize.xs'),
lineHeight: theme('lineHeight.4'),
whiteSpace: 'pre-wrap'
}
}
});
addUtilities({
'.separator': {
backgroundColor: '#ddd !important'
},
'.center-center': {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
'.ellipsize': {
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
},
'.disabled': {
pointerEvents: 'none',
cursor: 'default',
filter: 'grayscale(1)'
},
'.scrollbar-hidden': {
'-ms-overflow-style': 'none',
'scrollbar-width': 'none',
'&::-webkit-scrollbar': {
display: 'none',
width: '0px',
},
},
})
})
],
darkMode: 'class',
}