feat: demo flags (#1084)

This commit is contained in:
Jonas Plum
2024-07-21 04:07:23 +02:00
committed by GitHub
parent 91429effe2
commit a9e885598c
16 changed files with 217 additions and 108 deletions

View File

@@ -5,32 +5,32 @@
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%; /* zinc-950 */
--foreground: 20 14.3% 4.1%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--card-foreground: 20 14.3% 4.1%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--popover-foreground: 20 14.3% 4.1%;
--primary: 346.8 77.2% 49.8%;
--primary-foreground: 355.7 100% 97.3%;
--primary: 47.9 95.8% 53.1%;
--primary-foreground: 26 83.3% 14.1%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--secondary: 60 4.8% 95.9%;
--secondary-foreground: 24 9.8% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--muted: 60 4.8% 95.9%;
--muted-foreground: 25 5.3% 44.7%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%; /* zinc-900 */
--accent: 60 4.8% 95.9%;
--accent-foreground: 24 9.8% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--destructive-foreground: 60 9.1% 97.8%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 346.8 77.2% 49.8%;
--border: 20 5.9% 90%;
--input: 20 5.9% 90%;
--ring: 20 14.3% 4.1%;
--radius: 0.5rem;
--vis-tooltip-background-color: none !important;
@@ -49,38 +49,39 @@
@media (prefers-color-scheme: dark) {
:root {
--background: 20 14.3% 4.1%;
--foreground: 0 0% 95%;
--foreground: 60 9.1% 97.8%;
--card: 24 9.8% 10%;
--card-foreground: 0 0% 95%;
--card: 20 14.3% 4.1%;
--card-foreground: 60 9.1% 97.8%;
--popover: 0 0% 9%;
--popover-foreground: 0 0% 95%;
--popover: 20 14.3% 4.1%;
--popover-foreground: 60 9.1% 97.8%;
--primary: 346.8 77.2% 49.8%;
--primary-foreground: 355.7 100% 97.3%;
--primary: 47.9 95.8% 53.1%;
--primary-foreground: 26 83.3% 14.1%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--secondary: 12 6.5% 15.1%;
--secondary-foreground: 60 9.1% 97.8%;
--muted: 0 0% 15%;
--muted-foreground: 240 5% 64.9%;
--muted: 12 6.5% 15.1%;
--muted-foreground: 24 5.4% 63.9%;
--accent: 12 6.5% 15.1%;
--accent-foreground: 0 0% 98%;
--accent-foreground: 60 9.1% 97.8%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 85.7% 97.3%;
--destructive-foreground: 60 9.1% 97.8%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 346.8 77.2% 49.8%;
--border: 12 6.5% 15.1%;
--input: 12 6.5% 15.1%;
--ring: 35.5 91.7% 32.9%;
}
}
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
font-feature-settings:

View File

@@ -41,7 +41,10 @@ const {
const searchUserDebounced = debounce(() => refetch(), 300)
watch(searchTerm, () => searchUserDebounced())
watch(
() => searchTerm.value,
() => searchUserDebounced()
)
</script>
<template>

View File

@@ -24,9 +24,9 @@ onMounted(() => {
})
watch(
formdata,
(newVal) => {
model.value = { ...newVal }
() => formdata.value,
() => {
model.value = { ...formdata.value }
},
{ deep: true }
)

View File

@@ -30,7 +30,10 @@ const open = ref(false)
const searchTerm = ref('')
const selectedItems = ref<string[]>(props.modelValue)
watch(selectedItems.value, (value) => emit('update:modelValue', value))
watch(
() => selectedItems.value,
(value) => emit('update:modelValue', value)
)
const filteredItems = computed(() => {
if (!selectedItems.value) return props.items

View File

@@ -38,32 +38,36 @@ const updateReactionMutation = useMutation({
})
onMounted(() => {
pb.collection('reactions').subscribe(props.id, (data) => {
if (data.action === 'delete') {
toast({
title: 'Reaction deleted',
description: 'The reaction has been deleted.',
variant: 'destructive'
})
if (props.id) {
pb.collection('reactions').subscribe(props.id, (data) => {
if (data.action === 'delete') {
toast({
title: 'Reaction deleted',
description: 'The reaction has been deleted.',
variant: 'destructive'
})
router.push({ name: 'reactions' })
router.push({ name: 'reactions' })
return
}
return
}
if (data.action === 'update') {
toast({
title: 'Reaction updated',
description: 'The reaction has been updated.'
})
if (data.action === 'update') {
toast({
title: 'Reaction updated',
description: 'The reaction has been updated.'
})
queryClient.invalidateQueries({ queryKey: ['reactions', props.id] })
}
})
queryClient.invalidateQueries({ queryKey: ['reactions', props.id] })
}
})
}
})
onUnmounted(() => {
pb.collection('reactions').unsubscribe(props.id)
if (props.id) {
pb.collection('reactions').unsubscribe(props.id)
}
})
</script>

View File

@@ -3,6 +3,7 @@ import ActionPythonFormFields from '@/components/reaction/ActionPythonFormFields
import ActionWebhookFormFields from '@/components/reaction/ActionWebhookFormFields.vue'
import TriggerHookFormFields from '@/components/reaction/TriggerHookFormFields.vue'
import TriggerWebhookFormFields from '@/components/reaction/TriggerWebhookFormFields.vue'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import {
@@ -25,9 +26,11 @@ import {
} from '@/components/ui/select'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { useQuery } from '@tanstack/vue-query'
import { defineRule, useForm } from 'vee-validate'
import { computed, ref, watch } from 'vue'
import { pb } from '@/lib/pocketbase'
import type { Reaction } from '@/lib/types'
const submitDisabledReason = ref<string>('')
@@ -38,6 +41,24 @@ const props = defineProps<{
const emit = defineEmits(['submit'])
const isDemo = ref(false)
const { data: config } = useQuery({
queryKey: ['config'],
queryFn: (): Promise<Record<string, Array<String>>> => pb.send('/api/config', {})
})
watch(
() => config.value,
() => {
if (!config.value) return
if (config.value['flags'].includes('demo')) {
isDemo.value = true
}
},
{ immediate: true }
)
defineRule('required', (value: string) => {
if (!value || !value.length) {
return 'This field is required'
@@ -161,35 +182,42 @@ const equalReaction = (values: Reaction, reaction?: Reaction): boolean => {
)
}
const updateSubmitDisabledReason = () => {
if (isDemo.value) {
submitDisabledReason.value = 'Reactions cannot be created or edited in demo mode'
return
}
if (equalReaction(values, props.reaction)) {
submitDisabledReason.value = 'Make changes to save'
return
}
validate({ mode: 'silent' }).then((res) => {
if (res.valid) {
submitDisabledReason.value = ''
} else {
submitDisabledReason.value = 'Please fix the errors'
}
})
}
watch(
() => isDemo.value,
() => updateSubmitDisabledReason()
)
watch(
() => props.reaction,
() => {
if (equalReaction(values, props.reaction)) {
submitDisabledReason.value = 'Make changes to save'
} else {
submitDisabledReason.value = ''
}
},
() => updateSubmitDisabledReason(),
{ immediate: true }
)
watch(
values,
() => {
if (equalReaction(values, props.reaction)) {
submitDisabledReason.value = 'Make changes to save'
return
}
validate({ mode: 'silent' }).then((res) => {
if (res.valid) {
submitDisabledReason.value = ''
} else {
submitDisabledReason.value = 'Please fix the errors'
}
})
},
() => values,
() => updateSubmitDisabledReason(),
{ deep: true, immediate: true }
)
@@ -293,6 +321,10 @@ const curlExample = computed(() => {
</CardContent>
</Card>
<Alert v-if="isDemo" variant="destructive">
<AlertTitle>Cannot save</AlertTitle>
<AlertDescription>{{ submitDisabledReason }}</AlertDescription>
</Alert>
<div class="flex gap-4">
<TooltipProvider :delay-duration="0">
<Tooltip>

View File

@@ -5,7 +5,7 @@ import { Button } from '@/components/ui/button'
import { Separator } from '@/components/ui/separator'
import { useQuery, useQueryClient } from '@tanstack/vue-query'
import { onMounted, onUnmounted } from 'vue'
import { onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { pb } from '@/lib/pocketbase'
@@ -60,10 +60,6 @@ onMounted(() => {
queryClient.invalidateQueries({ queryKey: ['reactions'] })
})
})
onUnmounted(() => {
pb.collection('reactions').unsubscribe('*')
})
</script>
<template>
@@ -72,7 +68,7 @@ onUnmounted(() => {
<div class="flex items-center bg-background px-4 py-2">
<h1 class="text-xl font-bold">Reactions</h1>
<div class="ml-auto">
<Button variant="ghost" @click="openNew"> New Reaction </Button>
<Button variant="ghost" @click="openNew"> New Reaction</Button>
</div>
</div>
<Separator />

View File

@@ -117,7 +117,10 @@ watch(
)
const debouncedRefetch = debounce(refetch, 300)
watch(searchValue, () => debouncedRefetch())
watch(
() => searchValue.value,
() => debouncedRefetch()
)
watch([tab, props.selectedType, page, perPage], () => refetch())
</script>

View File

@@ -98,13 +98,16 @@ const state = ref({})
const name = ref('')
const description = ref('')
watch(isOpen, () => {
if (isOpen.value) {
name.value = ''
description.value = ''
state.value = {}
watch(
() => isOpen.value,
() => {
if (isOpen.value) {
name.value = ''
description.value = ''
state.value = {}
}
}
})
)
</script>
<template>

View File

@@ -31,12 +31,16 @@ const { data: config } = useQuery({
queryFn: (): Promise<Record<string, Array<String>>> => pb.send('/api/config', {})
})
watch(config, (newConfig) => {
if (!newConfig) return
if (newConfig['flags'].includes('demo')) {
isDemo.value = true
}
})
watch(
() => config.value,
(newConfig) => {
if (!newConfig) return
if (newConfig['flags'].includes('demo')) {
isDemo.value = true
}
},
{ immediate: true }
)
</script>
<template>

View File

@@ -52,11 +52,14 @@ const updateTimelineMutation = useMutation({
onError: handleError
})
watch(time, () => {
if (time.value) {
updateTimelineMutation.mutate({ time: time.value })
watch(
() => time.value,
() => {
if (time.value) {
updateTimelineMutation.mutate({ time: time.value })
}
}
})
)
const deleteTimelineItemMutation = useMutation({
mutationFn: () => pb.collection('timeline').delete(props.timelineItem.id),

View File

@@ -29,13 +29,16 @@ const { data: config } = useQuery({
queryFn: (): Promise<Record<string, Array<String>>> => pb.send('/api/config', {})
})
watch(config, (newConfig) => {
if (!newConfig) return
if (newConfig['flags'].includes('demo') || newConfig['flags'].includes('dev')) {
mail.value = 'user@catalyst-soar.com'
password.value = '1234567890'
watch(
() => config.value,
() => {
if (!config.value) return
if (config.value['flags'].includes('demo') || config.value['flags'].includes('dev')) {
mail.value = 'user@catalyst-soar.com'
password.value = '1234567890'
}
}
})
)
</script>
<template>

View File

@@ -1,4 +1,4 @@
<script setup lang="ts">
<script setup lang="ts" xmlns="http://www.w3.org/1999/html">
import ThreeColumn from '@/components/layout/ThreeColumn.vue'
import ReactionDisplay from '@/components/reaction/ReactionDisplay.vue'
import ReactionList from '@/components/reaction/ReactionList.vue'