Skip to content

Commit 4a59a98

Browse files
committed
extract template code into own files
1 parent e147bc4 commit 4a59a98

File tree

6 files changed

+230
-233
lines changed

6 files changed

+230
-233
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
@if (isLoading()) {
2+
<app-loading-spinner />
3+
} @else if (command(); as cmd) {
4+
<div class="container mx-auto px-4 py-8 max-w-6xl">
5+
<app-command-header [command]="cmd" />
6+
7+
<app-generated-command-display [command]="generatedCommand()" />
8+
9+
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
10+
<!-- Left Column: Flags and Options -->
11+
<div class="lg:col-span-2 space-y-6">
12+
@if (cmd.flags.length > 0) {
13+
<div class="bg-white rounded-lg shadow-md p-6">
14+
<h2 class="text-2xl font-bold mb-4">Flags</h2>
15+
<div class="space-y-3">
16+
@for (flag of cmd.flags; track flag.id) {
17+
<app-flag-item
18+
[flag]="flag"
19+
[selected]="getFlagState(flag.id)"
20+
(toggle)="toggleFlag(flag.id)"
21+
/>
22+
}
23+
</div>
24+
</div>
25+
}
26+
27+
@if (cmd.options.length > 0) {
28+
<div class="bg-white rounded-lg shadow-md p-6">
29+
<h2 class="text-2xl font-bold mb-4">Options</h2>
30+
<div class="space-y-4">
31+
@for (option of cmd.options; track option.id) {
32+
<app-option-item
33+
[option]="option"
34+
[selected]="getOptionState(option.id).selected"
35+
[value]="getOptionState(option.id).value"
36+
(toggle)="toggleOption(option.id)"
37+
(valueChange)="updateOptionValue(option.id, $event)"
38+
/>
39+
}
40+
</div>
41+
</div>
42+
}
43+
</div>
44+
45+
<!-- Right Column: Examples and Actions -->
46+
<div class="space-y-6">
47+
@if (cmd.examples && cmd.examples.length > 0) {
48+
<div class="bg-white rounded-lg shadow-md p-6">
49+
<h2 class="text-xl font-bold mb-4">Examples</h2>
50+
<div class="space-y-4">
51+
@for (example of cmd.examples; track example.command) {
52+
<app-example-card
53+
[example]="example"
54+
(apply)="applyExample(example)"
55+
/>
56+
}
57+
</div>
58+
</div>
59+
}
60+
61+
<div class="bg-white rounded-lg shadow-md p-6">
62+
<button
63+
(click)="saveCommand()"
64+
class="w-full px-4 py-3 bg-green-600 hover:bg-green-700 text-white font-semibold rounded-md transition-colors mb-2"
65+
[attr.aria-label]="'Save command to history'"
66+
>
67+
{{ saveButtonText() }}
68+
</button>
69+
<button
70+
(click)="resetCommand()"
71+
class="w-full px-4 py-3 bg-gray-600 hover:bg-gray-700 text-white font-semibold rounded-md transition-colors"
72+
[attr.aria-label]="'Reset command to default'"
73+
>
74+
Reset
75+
</button>
76+
</div>
77+
</div>
78+
</div>
79+
80+
<div class="mt-6">
81+
<app-command-history [commandId]="cmd.id" />
82+
</div>
83+
</div>
84+
} @else {
85+
<div class="container mx-auto px-4 py-8">
86+
<div class="bg-white rounded-lg shadow-md p-6 text-center">
87+
<h2 class="text-2xl font-bold text-gray-800">Command not found</h2>
88+
<p class="text-gray-600 mt-2">Please select a command from the navigation bar.</p>
89+
</div>
90+
</div>
91+
}

src/app/components/command-builder/command-builder.component.ts

Lines changed: 1 addition & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -34,99 +34,7 @@ interface OptionState {
3434
OptionItemComponent,
3535
ExampleCardComponent
3636
],
37-
template: `
38-
@if (isLoading()) {
39-
<app-loading-spinner />
40-
} @else if (command(); as cmd) {
41-
<div class="container mx-auto px-4 py-8 max-w-6xl">
42-
<app-command-header [command]="cmd" />
43-
44-
<app-generated-command-display [command]="generatedCommand()" />
45-
46-
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
47-
<!-- Left Column: Flags and Options -->
48-
<div class="lg:col-span-2 space-y-6">
49-
@if (cmd.flags.length > 0) {
50-
<div class="bg-white rounded-lg shadow-md p-6">
51-
<h2 class="text-2xl font-bold mb-4">Flags</h2>
52-
<div class="space-y-3">
53-
@for (flag of cmd.flags; track flag.id) {
54-
<app-flag-item
55-
[flag]="flag"
56-
[selected]="getFlagState(flag.id)"
57-
(toggle)="toggleFlag(flag.id)"
58-
/>
59-
}
60-
</div>
61-
</div>
62-
}
63-
64-
@if (cmd.options.length > 0) {
65-
<div class="bg-white rounded-lg shadow-md p-6">
66-
<h2 class="text-2xl font-bold mb-4">Options</h2>
67-
<div class="space-y-4">
68-
@for (option of cmd.options; track option.id) {
69-
<app-option-item
70-
[option]="option"
71-
[selected]="getOptionState(option.id).selected"
72-
[value]="getOptionState(option.id).value"
73-
(toggle)="toggleOption(option.id)"
74-
(valueChange)="updateOptionValue(option.id, $event)"
75-
/>
76-
}
77-
</div>
78-
</div>
79-
}
80-
</div>
81-
82-
<!-- Right Column: Examples and Actions -->
83-
<div class="space-y-6">
84-
@if (cmd.examples && cmd.examples.length > 0) {
85-
<div class="bg-white rounded-lg shadow-md p-6">
86-
<h2 class="text-xl font-bold mb-4">Examples</h2>
87-
<div class="space-y-4">
88-
@for (example of cmd.examples; track example.command) {
89-
<app-example-card
90-
[example]="example"
91-
(apply)="applyExample(example)"
92-
/>
93-
}
94-
</div>
95-
</div>
96-
}
97-
98-
<div class="bg-white rounded-lg shadow-md p-6">
99-
<button
100-
(click)="saveCommand()"
101-
class="w-full px-4 py-3 bg-green-600 hover:bg-green-700 text-white font-semibold rounded-md transition-colors mb-2"
102-
[attr.aria-label]="'Save command to history'"
103-
>
104-
{{ saveButtonText() }}
105-
</button>
106-
<button
107-
(click)="resetCommand()"
108-
class="w-full px-4 py-3 bg-gray-600 hover:bg-gray-700 text-white font-semibold rounded-md transition-colors"
109-
[attr.aria-label]="'Reset command to default'"
110-
>
111-
Reset
112-
</button>
113-
</div>
114-
</div>
115-
</div>
116-
117-
<div class="mt-6">
118-
<app-command-history [commandId]="cmd.id" />
119-
</div>
120-
</div>
121-
} @else {
122-
<div class="container mx-auto px-4 py-8">
123-
<div class="bg-white rounded-lg shadow-md p-6 text-center">
124-
<h2 class="text-2xl font-bold text-gray-800">Command not found</h2>
125-
<p class="text-gray-600 mt-2">Please select a command from the navigation bar.</p>
126-
</div>
127-
</div>
128-
}
129-
`
37+
templateUrl: './command-builder.component.html',
13038
})
13139
export class CommandBuilderComponent {
13240
private route = inject(ActivatedRoute);
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
@if (option(); as opt) {
2+
<div class="p-4 border border-gray-200 rounded-md hover:border-blue-300 transition-colors">
3+
<div class="flex items-start space-x-3 mb-3">
4+
<input
5+
type="checkbox"
6+
[id]="'option-' + opt.id"
7+
[checked]="selected()"
8+
(change)="toggle.emit()"
9+
class="mt-1 w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
10+
/>
11+
<label [attr.for]="'option-' + opt.id" class="flex-1 cursor-pointer">
12+
@if (opt.option) {
13+
<div class="font-mono font-semibold text-blue-600">{{ opt.option }}</div>
14+
}
15+
<div class="text-sm text-gray-600">
16+
{{ opt.description }}
17+
@if (opt.link) {
18+
<a [href]="opt.link" target="_blank" rel="noopener noreferrer" class="ml-1 text-blue-500 hover:text-blue-700 underline" (click)="$event.stopPropagation()">
19+
Learn more
20+
</a>
21+
}
22+
</div>
23+
</label>
24+
</div>
25+
26+
@if (opt.parameter && selected()) {
27+
<div class="ml-7 mt-2">
28+
@if (opt.parameter.type === 'text') {
29+
<input
30+
type="text"
31+
[id]="'param-' + opt.id"
32+
[value]="value() || ''"
33+
(input)="valueChange.emit($event)"
34+
[placeholder]="opt.parameter.placeholder || ''"
35+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
36+
[attr.aria-label]="opt.description + ' value'"
37+
/>
38+
}
39+
40+
@if (opt.parameter.type === 'number') {
41+
<input
42+
type="number"
43+
[id]="'param-' + opt.id"
44+
[value]="value() || ''"
45+
(input)="valueChange.emit($event)"
46+
[placeholder]="opt.parameter.placeholder || ''"
47+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
48+
[attr.aria-label]="opt.description + ' value'"
49+
/>
50+
}
51+
52+
@if (opt.parameter.type === 'enum' && opt.parameter.enumValues) {
53+
<select
54+
[id]="'param-' + opt.id"
55+
[value]="value() || opt.parameter.defaultValue || ''"
56+
(change)="valueChange.emit($event)"
57+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
58+
[attr.aria-label]="opt.description + ' value'"
59+
>
60+
<option value="">Select...</option>
61+
@for (enumVal of opt.parameter.enumValues; track enumVal.value) {
62+
<option [value]="enumVal.value" [title]="enumVal.description || ''">
63+
{{ enumVal.label }}
64+
</option>
65+
}
66+
</select>
67+
}
68+
</div>
69+
}
70+
</div>
71+
}

src/app/components/command-builder/components/option-item.component.ts

Lines changed: 1 addition & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,79 +5,7 @@ import { Option } from '../../../models/command.model';
55
@Component({
66
selector: 'app-option-item',
77
imports: [FormsModule],
8-
template: `
9-
@if (option(); as opt) {
10-
<div class="p-4 border border-gray-200 rounded-md hover:border-blue-300 transition-colors">
11-
<div class="flex items-start space-x-3 mb-3">
12-
<input
13-
type="checkbox"
14-
[id]="'option-' + opt.id"
15-
[checked]="selected()"
16-
(change)="toggle.emit()"
17-
class="mt-1 w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
18-
/>
19-
<label [attr.for]="'option-' + opt.id" class="flex-1 cursor-pointer">
20-
@if (opt.option) {
21-
<div class="font-mono font-semibold text-blue-600">{{ opt.option }}</div>
22-
}
23-
<div class="text-sm text-gray-600">
24-
{{ opt.description }}
25-
@if (opt.link) {
26-
<a [href]="opt.link" target="_blank" rel="noopener noreferrer" class="ml-1 text-blue-500 hover:text-blue-700 underline" (click)="$event.stopPropagation()">
27-
Learn more
28-
</a>
29-
}
30-
</div>
31-
</label>
32-
</div>
33-
34-
@if (opt.parameter && selected()) {
35-
<div class="ml-7 mt-2">
36-
@if (opt.parameter.type === 'text') {
37-
<input
38-
type="text"
39-
[id]="'param-' + opt.id"
40-
[value]="value() || ''"
41-
(input)="valueChange.emit($event)"
42-
[placeholder]="opt.parameter.placeholder || ''"
43-
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
44-
[attr.aria-label]="opt.description + ' value'"
45-
/>
46-
}
47-
48-
@if (opt.parameter.type === 'number') {
49-
<input
50-
type="number"
51-
[id]="'param-' + opt.id"
52-
[value]="value() || ''"
53-
(input)="valueChange.emit($event)"
54-
[placeholder]="opt.parameter.placeholder || ''"
55-
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
56-
[attr.aria-label]="opt.description + ' value'"
57-
/>
58-
}
59-
60-
@if (opt.parameter.type === 'enum' && opt.parameter.enumValues) {
61-
<select
62-
[id]="'param-' + opt.id"
63-
[value]="value() || opt.parameter.defaultValue || ''"
64-
(change)="valueChange.emit($event)"
65-
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
66-
[attr.aria-label]="opt.description + ' value'"
67-
>
68-
<option value="">Select...</option>
69-
@for (enumVal of opt.parameter.enumValues; track enumVal.value) {
70-
<option [value]="enumVal.value" [title]="enumVal.description || ''">
71-
{{ enumVal.label }}
72-
</option>
73-
}
74-
</select>
75-
}
76-
</div>
77-
}
78-
</div>
79-
}
80-
`
8+
templateUrl: './option-item.component.html'
819
})
8210
export class OptionItemComponent {
8311
option = input.required<Option>();

0 commit comments

Comments
 (0)