-
Screenshot
Edit existing task / import preset
Reset Form
diff --git a/frontend/wizard-vue/src/stores/wizard.ts b/frontend/wizard-vue/src/stores/wizard.ts
index bed82bb..ddd97b2 100644
--- a/frontend/wizard-vue/src/stores/wizard.ts
+++ b/frontend/wizard-vue/src/stores/wizard.ts
@@ -1,5 +1,5 @@
import {defineStore} from "pinia";
-import {emptySpecs, type Field, type FieldNames, fields, type Specs} from "@/urlmaker/specs.ts";
+import {emptySpecs, type SpecField, fields, type Specs} from "@/urlmaker/specs.ts";
import {computed, reactive} from "vue";
import {debounce} from "es-toolkit";
@@ -14,7 +14,7 @@ export const useWizardStore = defineStore('wizard', () => {
const formValid = computed(() => {
return fields.every(field => (
- specs[field.name].length === 0 && !(field as Field).required || field.validate(specs[field.name]).ok
+ !specs[field.name] && !(field as SpecField).required || field.validate(specs[field.name]!)
));
});
@@ -22,7 +22,7 @@ export const useWizardStore = defineStore('wizard', () => {
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(specs));
}, 100);
- function updateSpec(fieldName: FieldNames, newValue: string) {
+ function updateSpec(fieldName: keyof Specs, newValue: string) {
specs[fieldName] = newValue;
updateLocalStorage();
}
diff --git a/frontend/wizard-vue/src/urlmaker/specs.ts b/frontend/wizard-vue/src/urlmaker/specs.ts
index f0c61c0..0307b53 100644
--- a/frontend/wizard-vue/src/urlmaker/specs.ts
+++ b/frontend/wizard-vue/src/urlmaker/specs.ts
@@ -4,20 +4,34 @@ import {
validateUrl,
type validator
} from "@/urlmaker/validators.ts";
+import {rssalchemy} from "@/urlmaker/proto/specs.ts";
-export interface Field {
- name: string
- input_type: string
- label: string
- default: string
- validate: validator
- required?: boolean
+export type SpecKey = ReturnType;
+export type SpecValue = string | number;
+export type Specs = {[k in keyof SpecKey]: SpecValue};
+
+export enum InputType {
+ Url = 'url',
+ Text = 'text',
+ Radio = 'radio'
}
-export const fields = [
+export interface SpecField {
+ name: keyof Specs
+ input_type: InputType
+ enum_values?: {[k: number]: string}
+ label: string
+ default: SpecValue
+ validate: validator
+ required?: boolean
+ group?: string
+ show_if?: (specs: Specs) => boolean
+}
+
+export const fields: SpecField[] = [
{
name: 'url',
- input_type: 'url',
+ input_type: InputType.Url,
label: 'URL of page for converting',
default: '',
validate: validateUrl,
@@ -25,72 +39,71 @@ export const fields = [
},
{
name: 'selector_post',
- input_type: 'text',
+ input_type: InputType.Text,
label: 'CSS Selector for post',
default: '',
validate: validateSelector,
},
{
name: 'selector_title',
- input_type: 'text',
+ input_type: InputType.Text,
label: 'CSS Selector for title',
default: '',
validate: validateSelector,
},
{
name: 'selector_link',
- input_type: 'text',
+ input_type: InputType.Text,
label: 'CSS Selector for link',
default: '',
validate: validateSelector,
},
{
name: 'selector_description',
- input_type: 'text',
+ input_type: InputType.Text,
label: 'CSS Selector for description',
default: '',
validate: validateSelector,
},
{
name: 'selector_author',
- input_type: 'text',
+ input_type: InputType.Text,
label: 'CSS Selector for author',
default: '',
validate: validateSelector,
},
+
{
name: 'selector_created',
- input_type: 'text',
+ input_type: InputType.Text,
label: 'CSS Selector for created date',
default: '',
validate: validateSelector,
+ group: 'created',
},
+
{
name: 'selector_content',
- input_type: 'text',
+ input_type: InputType.Text,
label: 'CSS Selector for content',
default: '',
validate: validateSelector,
},
{
name: 'selector_enclosure',
- input_type: 'text',
+ input_type: InputType.Text,
label: 'CSS Selector for enclosure (e.g. image url)',
default: '',
validate: validateSelector,
},
{
name: 'cache_lifetime',
- input_type: 'text',
+ input_type: InputType.Text,
label: 'Cache lifetime (format examples: 10s, 1m, 2h)',
default: '10m',
validate: validateDuration,
},
-] as const satisfies Field[];
-
-export type FieldNames = (typeof fields)[number]['name'];
-
-export type Specs = {[k in FieldNames]: string};
+];
export const emptySpecs = fields.reduce((o, f) => {
o[f.name] = f.default;
diff --git a/frontend/wizard-vue/src/urlmaker/validators.ts b/frontend/wizard-vue/src/urlmaker/validators.ts
index aaa55b0..62015f4 100644
--- a/frontend/wizard-vue/src/urlmaker/validators.ts
+++ b/frontend/wizard-vue/src/urlmaker/validators.ts
@@ -1,54 +1,31 @@
import {presetPrefix} from "@/urlmaker/index.ts";
+import type {SpecValue} from "@/urlmaker/specs.ts";
-type validResult = { ok: boolean, error?: string };
-export type validator = (v: string) => validResult
+export type validator = (v: SpecValue) => boolean;
-export function validateUrl(s: string): validResult {
+export function validateUrl(s: SpecValue): boolean {
let url;
try {
- url = new URL(s);
- return {
- ok: url.protocol === "http:" || url.protocol === "https:",
- error: 'Invalid URL protocol',
- };
+ url = new URL(s as string);
+ return url.protocol === "http:" || url.protocol === "https:"
} catch {
- return {ok: false, error: 'Invalid URL'};
+ return false;
}
}
-export function validatePreset(s: string): validResult {
- if(!s.startsWith(presetPrefix)) {
- return {
- ok: false,
- error: 'Not a preset'
- }
- }
- return {ok: true}
+export function validatePreset(s: SpecValue): boolean {
+ return (s as string).startsWith(presetPrefix);
}
-export function validateOr(...validators: validator[]): validator {
- return function(s: string): validResult {
- return validators.reduce((res, v) => {
- let r = v(s);
- if(r.ok) res.ok = true;
- else res.error += r.error + '; ';
- return res;
- }, {ok: false, error: ''});
- }
-}
-
-export function validateSelector(s: string): validResult {
+export function validateSelector(s: SpecValue): boolean {
try {
- document.createDocumentFragment().querySelector(s);
- return {ok: true}
+ document.createDocumentFragment().querySelector(s as string);
+ return true;
} catch {
- return {ok: false, error: 'Invalid selector'};
+ return false;
}
}
-export function validateDuration(s: string): validResult {
- return {
- ok: /^\d+[smh]$/.test(s),
- error: 'Duration must be number and unit (s/m/h), example: 5s = 5 seconds'
- }
+export function validateDuration(s: SpecValue): boolean {
+ return /^\d+[smh]$/.test(s as string);
}