Skip to content

Commit 74cb86a

Browse files
committed
update snippet when command is moved or deleted
1 parent 1eb23fc commit 74cb86a

File tree

23 files changed

+224
-115
lines changed

23 files changed

+224
-115
lines changed

editor/src/app/components/commands/command-editor/command-editor.component.html

Lines changed: 90 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -19,50 +19,49 @@ <h5>
1919
<div class="scroll-container">
2020
<div class="row mb-2">
2121
<div class="col-12 flex-row d-flex justify-content-end">
22-
<button
23-
[disabled]="!command.name"
24-
class="btn btn-outline-secondary mr-2 dropdown-toggle"
25-
data-toggle="dropdown"
26-
data-offset="0,0"
27-
aria-haspopup="true"
28-
aria-expanded="false"
29-
[title]="'ui.commandEditor.copyFromHint' | translate"
30-
>
31-
{{ "ui.commandEditor.copyFrom" | translate }}
32-
</button>
33-
<div class="dropdown-menu">
34-
<span
35-
class="dropdown-item"
36-
*ngFor="let target of games"
37-
(click)="copyFromCommand(target)"
38-
>{{ target | gameTitle }}</span
22+
<div>
23+
<button
24+
[disabled]="!command.name"
25+
class="btn btn-outline-secondary mr-2 dropdown-toggle"
26+
data-toggle="dropdown"
27+
data-offset="0,0"
28+
aria-haspopup="true"
29+
aria-expanded="false"
30+
[title]="'ui.commandEditor.copyFromHint' | translate"
3931
>
32+
{{ "ui.commandEditor.copyFrom" | translate }}
33+
</button>
34+
<div class="dropdown-menu">
35+
<span
36+
class="dropdown-item"
37+
*ngFor="let target of games"
38+
(click)="copyFromCommand(target)"
39+
>{{ target | gameTitle }}</span
40+
>
41+
</div>
4042
</div>
41-
<button
42-
*ngIf="canClone()"
43-
[disabled]="isInvalid"
44-
class="btn btn-outline-secondary mr-2 dropdown-toggle"
45-
data-toggle="dropdown"
46-
data-offset="0,0"
47-
aria-haspopup="true"
48-
aria-expanded="false"
49-
>
50-
{{ "ui.shared.clone" | translate }}
51-
</button>
52-
<div class="dropdown-menu">
53-
<span
54-
class="dropdown-item"
55-
*ngFor="let target of cloneTargets"
56-
(click)="cloneCommand(target)"
57-
>{{ target | gameTitle }}</span
43+
44+
<div>
45+
<button
46+
*ngIf="canClone()"
47+
[disabled]="isInvalid"
48+
class="btn btn-outline-secondary mr-2 dropdown-toggle"
49+
data-toggle="dropdown"
50+
data-offset="0,0"
51+
aria-haspopup="true"
52+
aria-expanded="false"
5853
>
54+
{{ "ui.shared.clone" | translate }}
55+
</button>
56+
<div class="dropdown-menu">
57+
<span
58+
class="dropdown-item"
59+
*ngFor="let target of cloneTargets"
60+
(click)="cloneCommand(target)"
61+
>{{ target | gameTitle }}</span
62+
>
63+
</div>
5964
</div>
60-
<button
61-
class="btn btn-outline-secondary text-nowrap"
62-
(click)="addInput()"
63-
>
64-
{{ "ui.commandEditor.addInput" | translate }}
65-
</button>
6665
<scl-icon-button
6766
class="ml-3 text-danger"
6867
icon="delete"
@@ -284,14 +283,37 @@ <h5>
284283
</div>
285284

286285
<ng-container cdkDropListGroup>
286+
<div
287+
class="flex-row d-flex align-items-center justify-content-between mb-2"
288+
>
289+
<h5>{{ "ui.commandEditor.paramsSubtitle" | translate }}</h5>
290+
<button
291+
class="btn btn-outline-secondary text-nowrap"
292+
(click)="addInput()"
293+
[title]="'ui.commandEditor.addInput' | translate"
294+
>
295+
<svg
296+
style="margin-top: -3px"
297+
xmlns="http://www.w3.org/2000/svg"
298+
width="16"
299+
height="16"
300+
fill="currentColor"
301+
class="bi bi-plus"
302+
viewBox="0 0 16 16"
303+
>
304+
<path
305+
d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"
306+
/>
307+
</svg>
308+
{{ "ui.layout.new" | translate }}
309+
</button>
310+
</div>
287311
<div
288312
cdkDropList
289313
[cdkDropListData]="command.input"
290314
[ngClass]="{ 'empty-list': !command.input?.length }"
291315
(cdkDropListDropped)="drop($event, SourceType.any)"
292316
>
293-
<h5>{{ "ui.commandEditor.paramsSubtitle" | translate }}</h5>
294-
295317
<div
296318
*ngFor="let param of command.input; let i = index"
297319
cdkDrag
@@ -366,13 +388,37 @@ <h5>{{ "ui.commandEditor.paramsSubtitle" | translate }}</h5>
366388
</div>
367389
</div>
368390

391+
<div
392+
class="flex-row d-flex align-items-center justify-content-between mb-2"
393+
>
394+
<h5>{{ "ui.commandEditor.resultSubtitle" | translate }}</h5>
395+
<button
396+
class="btn btn-outline-secondary text-nowrap"
397+
(click)="addOutput()"
398+
[title]="'ui.commandEditor.addOutput' | translate"
399+
>
400+
<svg
401+
style="margin-top: -3px"
402+
xmlns="http://www.w3.org/2000/svg"
403+
width="16"
404+
height="16"
405+
fill="currentColor"
406+
class="bi bi-plus"
407+
viewBox="0 0 16 16"
408+
>
409+
<path
410+
d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"
411+
/>
412+
</svg>
413+
{{ "ui.layout.new" | translate }}
414+
</button>
415+
</div>
369416
<div
370417
cdkDropList
371418
[cdkDropListData]="command.output"
372419
[ngClass]="{ 'empty-list': !command.output?.length }"
373420
(cdkDropListDropped)="drop($event, SourceType.var_any)"
374421
>
375-
<h5>{{ "ui.commandEditor.resultSubtitle" | translate }}</h5>
376422
<div
377423
*ngFor="let param of command.output; let i = index"
378424
cdkDrag
@@ -578,9 +624,7 @@ <h5>
578624
</div>
579625
<div
580626
class="full-description"
581-
[innerHTML]="
582-
fullDescription[0] | markdown | sanitize
583-
"
627+
[innerHTML]="fullDescription[0] | markdown | sanitize"
584628
></div>
585629
</div>
586630
</div>

editor/src/app/components/commands/command-editor/command-editor.component.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,17 @@ export class CommandEditorComponent implements OnInit {
787787
this.updateErrors();
788788
}
789789

790+
addOutput() {
791+
this.command.output ??= [];
792+
this.command.output.push({
793+
name: '',
794+
type: PrimitiveType.any,
795+
source: DEFAULT_OUTPUT_SOURCE,
796+
});
797+
this.command.num_params++;
798+
this.updateErrors();
799+
}
800+
790801
deleteCommand() {
791802
this.delete.emit();
792803
}

editor/src/app/components/library-page/library-page.component.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,11 @@ export class LibraryPageComponent implements OnInit, OnDestroy, AfterViewInit {
121121
canGoBackInDecisionTree$ = this._tree.currentNode$.pipe(
122122
map((node) => node && node.id !== 'root')
123123
);
124-
isCustomFilterSelected$ = this._ui.isCustomFilterSelected$
125-
124+
isCustomFilterSelected$ = this._ui.isCustomFilterSelected$;
126125

127126
command?: Command;
128127
oldCommand?: Command;
129-
snippet?: string;
128+
snippet?: string | null;
130129
oldSnippet?: string;
131130
extension?: string;
132131
oldExtension?: string;
@@ -236,6 +235,9 @@ export class LibraryPageComponent implements OnInit, OnDestroy, AfterViewInit {
236235

237236
onDeleteCommand(command: Command, game: Game) {
238237
this._extensions.markCommandsToDelete([command.name], game);
238+
if (this.snippet !== undefined) {
239+
this.snippet = null; // mark snippet to delete
240+
}
239241
this._onSaveCommand(true);
240242
}
241243

@@ -567,9 +569,13 @@ export class LibraryPageComponent implements OnInit, OnDestroy, AfterViewInit {
567569
updateRelated: this.updateRelatedCommands,
568570
});
569571
}
570-
if (this.snippet !== this.oldSnippet) {
572+
if (
573+
this.snippet !== this.oldSnippet ||
574+
this.extension !== this.oldExtension
575+
) {
571576
this._snippets.updateSnippet({
572-
extension: this.extension!,
577+
newExtension: this.extension!,
578+
oldExtension: this.oldExtension!,
573579
command: this.command!,
574580
content: this.snippet!,
575581
updateRelated: this.updateRelatedCommands,

editor/src/app/state/changes/actions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const registerExtensionsChange = createAction(
1515

1616
export const registerTextFileChange = createAction(
1717
'[changes] register snippet',
18-
props<{ fileName: string; content: string }>()
18+
props<{ fileName: string; content: string | null }>()
1919
);
2020

2121
export const registerEnumChange = createAction(
@@ -45,7 +45,7 @@ export const registerFileContent = createAction(
4545

4646
export const validateAndWriteFiles = createAction(
4747
'[changes] validate and write files',
48-
props<{ files: Array<{ path: string; content: string }> }>()
48+
props<{ files: Array<{ path: string; content: string | null }> }>()
4949
);
5050

5151
export const loadGitTree = createAction('[changes] load git tree');

editor/src/app/state/changes/effects.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export class ChangesEffects {
6767
switchMap(([{ files }, accessToken]) => {
6868
return zip(
6969
...files.map((file) => {
70-
if (!isExtensionFile(file.path)) {
70+
if (!isExtensionFile(file.path) || !file.content) {
7171
return of(file);
7272
}
7373
const game = gameByExtensionFile(file.path);
@@ -89,7 +89,7 @@ export class ChangesEffects {
8989
const patch = diff.createPatch(
9090
file.path,
9191
snapshots[file.path].content,
92-
file.content
92+
file.content!
9393
);
9494
const newContent = JSON.stringify(response, null, 2);
9595
return {

editor/src/app/state/changes/facade.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
loadGitTree,
1313
} from './actions';
1414
import * as selector from './selectors';
15-
import { filter, tap } from 'rxjs/operators';
1615

1716
@Injectable({ providedIn: 'root' })
1817
export class ChangesFacade {
@@ -52,7 +51,7 @@ export class ChangesFacade {
5251
);
5352
}
5453

55-
registerTextFileChange(fileName: string, content: string) {
54+
registerTextFileChange(fileName: string, content: string | null) {
5655
this.store$.dispatch(registerTextFileChange({ fileName, content }));
5756
}
5857

editor/src/app/state/changes/reducer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121

2222
type FileName = string;
2323
export interface ChangesState {
24-
changes: Record<FileName, string>;
24+
changes: Record<FileName, string | null>;
2525
snapshots: Record<FileName, { lastUpdate: number; content: string }>;
2626
github?: KoreFile;
2727
lastUpdate?: number;

editor/src/app/state/extensions/reducer.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ export const extensionsReducer = createReducer(
7575
memo,
7676
{
7777
command: newCommand,
78-
newExtension: name,
78+
newExtension,
7979
oldExtension,
8080
ignoreVersionAndPlatform,
8181
}
8282
) => {
8383
memo = upsertBy(
8484
memo,
85-
(extension) => extension.name === name,
85+
(extension) => extension.name === newExtension,
8686
'name',
8787
(e) => ({
8888
...e,
@@ -109,10 +109,10 @@ export const extensionsReducer = createReducer(
109109
: newCommand
110110
),
111111
}),
112-
() => ({ name, commands: [newCommand] })
112+
() => ({ name: newExtension, commands: [newCommand] })
113113
);
114114

115-
if (name === oldExtension) {
115+
if (newExtension === oldExtension) {
116116
return memo;
117117
}
118118

editor/src/app/state/github/GitHubAdaptor.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export interface GitCommitPushOptions {
1010
repo: string;
1111
files: {
1212
path: string;
13-
content: string | ArrayBuffer;
13+
content: string | null;
1414
}[];
1515
ref: string;
1616
forceUpdate?: boolean;
@@ -70,7 +70,15 @@ const createTree = (
7070
type: 'blob',
7171
} as const;
7272
});
73+
} else if (file.content === null) {
74+
return Promise.resolve({
75+
sha: null,
76+
path: file.path,
77+
mode: '100644',
78+
type: 'blob',
79+
} as const);
7380
}
81+
7482
throw new Error(`This file can not handled: ${file}`);
7583
});
7684
return Promise.all(promises).then((files) => {

editor/src/app/state/github/korefile.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
export interface KoreFile {
22
readFile(filePath: string): Promise<string>;
33

4-
writeFile(filePath: string, content: string | ArrayBuffer): Promise<void>;
4+
writeFile(filePath: string, content: string | null): Promise<void>;
55

6-
writeFiles(
7-
files: { path: string; content: string | ArrayBuffer }[]
8-
): Promise<void>;
6+
writeFiles(files: { path: string; content: string | null }[]): Promise<void>;
97

108
deleteFile(filePath: string): Promise<void>;
119
}
@@ -18,11 +16,11 @@ export const createKoreFile = ({ adaptor }: { adaptor: any }): KoreFile => {
1816
readFile(filePath: string): Promise<string> {
1917
return adaptor.readFile(filePath);
2018
},
21-
writeFile(filePath: string, content: string | ArrayBuffer): Promise<void> {
19+
writeFile(filePath: string, content: string | null): Promise<void> {
2220
return adaptor.writeFile(filePath, content);
2321
},
2422
writeFiles(
25-
files: { path: string; content: string | ArrayBuffer }[]
23+
files: { path: string; content: string | null }[]
2624
): Promise<void> {
2725
return adaptor.writeFiles(files);
2826
},

0 commit comments

Comments
 (0)