Skip to content

Commit fb88347

Browse files
committed
Add dropdown menu to new pipeline button
1 parent d756416 commit fb88347

File tree

5 files changed

+58
-34
lines changed

5 files changed

+58
-34
lines changed

app/components/DomExplorer/Pipe/PipeCreateButton.vue

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
@update:model-value="create"
88
>
99
<template #button>
10-
<Button size="icon" class="size-6">
11-
<Icon name="plus" class="size-5" />
12-
</Button>
10+
<slot>
11+
<Button size="icon" class="size-6">
12+
<Icon name="plus" class="size-5" />
13+
</Button>
14+
</slot>
1315
</template>
1416
</SearchInput>
1517
</template>
@@ -18,8 +20,13 @@
1820
import { createPipe, isValidPipeName, type Pipe } from "~/types";
1921
import { pipes } from "../Pipes";
2022
23+
const props = defineProps<{
24+
allowEmpty?: boolean;
25+
}>();
26+
2127
const emit = defineEmits<{
2228
create: [Pipe];
29+
createEmpty: [];
2330
}>();
2431
2532
const { presets } = usePresets();
@@ -44,18 +51,29 @@ const groups = computed(() => {
4451
items: (string | { label: string; value: string })[];
4552
}[] = [];
4653
54+
if (props.allowEmpty) {
55+
groups.push({
56+
name: "",
57+
items: [
58+
{
59+
label: "Empty",
60+
value: "$empty",
61+
},
62+
],
63+
});
64+
}
65+
4766
// Force the order
67+
if (presetsChoices.value.length > 0) {
68+
groups.push({ name: "Preset", items: presetsChoices.value });
69+
}
4870
groups.push({ name: "DEV", items: [] });
4971
groups.push({ name: "Preset", items: [] });
5072
groups.push({ name: "Parser", items: [] });
5173
groups.push({ name: "Sanitizer", items: [] });
5274
groups.push({ name: "Render", items: [] });
5375
groups.push({ name: "Other", items: [] });
5476
55-
if (presetsChoices.value.length > 0) {
56-
groups.push({ name: "Preset", items: presetsChoices.value });
57-
}
58-
5977
pipes.forEach((pipe) => {
6078
const group = groups.find((g) => g.name === pipe.category);
6179
if (group) {
@@ -70,11 +88,15 @@ const groups = computed(() => {
7088
});
7189
7290
function create(name: string) {
91+
if (name === "$empty") {
92+
emit("createEmpty");
93+
return;
94+
}
7395
if (name.startsWith("preset:")) {
7496
const preset = presets.value.find((p) => p.id === name.slice(7));
7597
if (!preset) return;
7698
for (const pipe of preset.pipes) {
77-
emit("create", pipe);
99+
emit("create", clonePipe(pipe));
78100
}
79101
} else if (isValidPipeName(name)) {
80102
const newPipe = createPipe(name);

app/components/DomExplorer/SyncMode/SyncModeDialog.vue

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
<template>
22
<Dialog v-model:open="open">
33
<DialogTrigger>
4-
<Button class="h-8 capitalize">{{ buttonTitle }}</Button>
4+
<Button class="h-8 capitalize">
5+
<Icon name="cable" class="mr-2" />
6+
{{ buttonTitle }}
7+
</Button>
58
</DialogTrigger>
69
<DialogContent>
710
<DialogHeader>
811
<DialogTitle>Sync Tabs</DialogTitle>
9-
<DialogDescription class="sr-only"> Sync tabs</DialogDescription>
12+
<DialogDescription>
13+
You can use this feature to sync tabs between different browser.
14+
Synched tabs will be updated in real-time.
15+
</DialogDescription>
1016
</DialogHeader>
1117

1218
<SyncModeConnectionTable />
@@ -15,7 +21,7 @@
1521
<Button @click="start">Start pairing</Button>
1622
<Button @click="join">Join pairing</Button>
1723
</div>
18-
<div v-else class="mt-2 h-1 w-full bg-border"/>
24+
<div v-else class="mt-2 h-1 w-full bg-border" />
1925
<SyncModeStartPairing
2026
v-if="connection && tab === 'start'"
2127
:connection="connection"

app/components/ui/icon/all.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ export { RefreshCwIcon } from "lucide-vue-next";
2121
export { NetworkIcon } from "lucide-vue-next";
2222
export { DicesIcon } from "lucide-vue-next";
2323
export { ScanTextIcon } from "lucide-vue-next";
24+
export { BookMarkedIcon } from "lucide-vue-next";

app/pages/dom-explorer/index.vue

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@
66
<SyncModeDialog />
77
<PresetsDialog>
88
<Button class="h-8">
9-
<Icon name="settings" class="mr-2" />
9+
<Icon name="bookMarked" class="mr-2" />
1010
Presets
1111
</Button>
1212
</PresetsDialog>
13-
<Button class="h-8" @click="addPipeline">
14-
<Icon name="plus" class="mr-2" />
15-
Pipeline
16-
</Button>
13+
<PipeCreateButton
14+
allow-empty
15+
@create="addPipeline"
16+
@create-empty="addPipeline"
17+
>
18+
<Button class="h-8">
19+
<Icon name="plus" class="mr-2" />
20+
Pipeline
21+
</Button>
22+
</PipeCreateButton>
1723
</div>
1824
</template>
1925
</LayoutHeader>
@@ -40,6 +46,8 @@
4046
</template>
4147

4248
<script lang="ts" setup>
49+
import type { Pipe } from "~/types";
50+
4351
const state = ref(parseStateFromHash());
4452
4553
onMounted(() => {
@@ -59,24 +67,11 @@ createDomExplorerSettings({
5967
},
6068
});
6169
62-
function addPipeline() {
70+
function addPipeline(pipe?: Pipe) {
6371
state.value.pipelines.push({
6472
id: randomId(),
6573
name: `Pipeline ${state.value.pipelines.length + 1}`,
66-
pipes: [
67-
{
68-
name: "DomParser",
69-
id: randomId(),
70-
hide: false,
71-
skip: false,
72-
opts: {
73-
addDoctype: false,
74-
output: "innerHTML",
75-
selector: "body",
76-
type: "text/html",
77-
},
78-
},
79-
],
74+
pipes: pipe ? [pipe] : [],
8075
});
8176
}
8277

app/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { pipeParser, pipes } from "~/components/DomExplorer/Pipes";
33

44
export const pipeNames = pipes.map((pipe) => pipe.name);
55

6-
export interface Pipe<T extends object = object> {
6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7+
export interface Pipe<T = any> {
78
name: string;
89
id: string;
910
hide: boolean;
@@ -75,13 +76,12 @@ export type DomExplorerState = z.infer<typeof stateParser>;
7576
export type DomExplorerSettings = z.infer<typeof settingsParser>;
7677

7778
export type JSONValue = string | number | boolean | JSONObject | JSONArray;
78-
export type JSONArray = JSONValue[]
79+
export type JSONArray = JSONValue[];
7980

8081
export interface JSONObject {
8182
[x: string]: JSONValue;
8283
}
8384

84-
8585
export function isValidPipeName(name: string): boolean {
8686
return (pipeNames as string[]).includes(name);
8787
}

0 commit comments

Comments
 (0)