Skip to content

Commit 747adb6

Browse files
authored
Merge pull request #25 from coder/brett/improve-rendering
fix: force re-mount component only when owner changes or reset
2 parents a88ac7c + 997f6de commit 747adb6

File tree

3 files changed

+69
-15
lines changed

3 files changed

+69
-15
lines changed

src/client/Preview.tsx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import {
5555
SelectValue,
5656
} from "@/client/components/Select";
5757
import { mockUsers } from "@/owner";
58+
import { checkerModule } from "./snippets";
5859

5960
export const Preview: FC = () => {
6061
const $wasmState = useStore((state) => state.wasmState);
@@ -107,6 +108,7 @@ export const Preview: FC = () => {
107108
const rawOutput = await window.go_preview?.(
108109
{
109110
"main.tf": debouncedCode,
111+
"checker/main.tf": checkerModule,
110112
},
111113
$owner,
112114
$form,
@@ -529,24 +531,28 @@ const Log: FC<LogProps> = ({ log }) => {
529531
type FormProps = { parameters: ParameterWithSource[] };
530532

531533
const Form: FC<FormProps> = ({ parameters }) => {
532-
return parameters
533-
.sort((a, b) => a.order - b.order)
534-
// Since the form is sourced from constantly changing terraform, we are not sure
535-
// if the parameters are the "same" as the previous render.
536-
.map((p) => <FormElement key={window.crypto.randomUUID()} parameter={p} />);
534+
const $force = useStore((state) => state._force);
535+
536+
const getParameterHash = (p: ParameterWithSource) =>
537+
`${$force}:${p.name}:${p.form_type}`;
538+
539+
return (
540+
parameters
541+
.sort((a, b) => a.order - b.order)
542+
// Since the form is sourced from constantly changing terraform, we are not sure
543+
// if the parameters are the "same" as the previous render.
544+
.map((p) => <FormElement key={getParameterHash(p)} parameter={p} />)
545+
);
537546
};
538547

539548
type FormElementProps = { parameter: ParameterWithSource };
540549
const FormElement: FC<FormElementProps> = ({ parameter }) => {
541550
const $form = useStore((state) => state.form);
542551
const $setForm = useStore((state) => state.setFormState);
543552

544-
const value = useMemo(
545-
() =>
546-
$form[parameter.name] ??
547-
undefined,
548-
[$form, parameter],
549-
);
553+
const value = useMemo(() => {
554+
return $form[parameter.name];
555+
}, [$form, parameter.name]);
550556

551557
const onValueChange = (value: string) => {
552558
$setForm(parameter.name, value);

src/client/snippets.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const textInput = `data "coder_parameter" "project-name" {
1111
display_name = "An input"
1212
name = "an-input"
1313
description = "What is the name of your project?"
14-
order = 1
14+
order = 4
1515
1616
form_type = "input"
1717
type = "string"
@@ -94,3 +94,38 @@ export const switchInput = `data "coder_parameter" "switch" {
9494
defalt = true
9595
order = 1
9696
}`
97+
98+
export const checkerModule = `
99+
variable "solutions" {
100+
type = map(list(string))
101+
}
102+
variable "guess" {
103+
type = list(string)
104+
}
105+
locals {
106+
# [for connection, solution in local.solutions : connection if (length(setintersection(solution, jsondecode(data.coder_parameter.rows["yellow"].value))) == 4)]
107+
diff = [for connection, solution in var.solutions : {
108+
connection = connection
109+
distance = 4 - length(setintersection(solution, var.guess))
110+
}]
111+
solved = [for diff in local.diff : diff.connection if diff.distance == 0]
112+
one_away = [for diff in local.diff : diff.connection if diff.distance == 1]
113+
description = length(local.one_away) == 1 && length(var.guess) == 4 ? "One away..." : (
114+
length(local.solved) == 1 ? "Solved!" : (
115+
"Select 4 words that share a common connection."
116+
)
117+
)
118+
}
119+
output "out" {
120+
value = local.one_away
121+
}
122+
output "title" {
123+
value = length(local.solved) == 1 ? "\${local.solved[0]}" : "??"
124+
}
125+
output "description" {
126+
value = local.description
127+
}
128+
output "solved" {
129+
value = length(local.solved) == 1 ? true : false
130+
}
131+
`;

src/client/store.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { create } from "zustand";
55
import { defaultCode } from "./snippets";
66
import { mockUsers } from "@/owner";
77

8-
type FormState = Record<string, string>;
8+
export type FormState = Record<string, string>;
99

1010
type WasmState = "loaded" | "loading" | "error";
1111

@@ -19,6 +19,7 @@ const defaultErrorsState: ErrorsState = {
1919
};
2020

2121
type State = {
22+
_force: number;
2223
code: string;
2324
editor: editor.IStandaloneCodeEditor | null;
2425
parameters: ParameterWithSource[];
@@ -38,6 +39,7 @@ type State = {
3839
};
3940

4041
export const useStore = create<State>()((set) => ({
42+
_force: 0,
4143
code: window.CODE ?? defaultCode,
4244
editor: null,
4345
parameters: [],
@@ -72,7 +74,18 @@ export const useStore = create<State>()((set) => ({
7274

7375
return { form };
7476
}),
75-
resetForm: () => set(() => ({ form: {} })),
77+
resetForm: () =>
78+
set((state) => ({
79+
form: {},
80+
_force: state._force + 1,
81+
})),
7682
setEditor: (editor) => set(() => ({ editor })),
77-
setWorkspaceOwner: (owner) => set(() => ({ owner })),
83+
setWorkspaceOwner: (owner) =>
84+
set((state) => ({
85+
...state,
86+
owner,
87+
_force: state._force + 1,
88+
form: {},
89+
parameters: [...state.parameters],
90+
})),
7891
}));

0 commit comments

Comments
 (0)