Add save status changes to the dedicated user label editor.
This commit is contained in:
parent
45d9f03b50
commit
7a73aa57c3
|
@ -27,8 +27,8 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
hasUnsavedChanges: boolean;
|
|
||||||
newLabelUsername: string;
|
newLabelUsername: string;
|
||||||
|
unsavedUserLabelIds: Set<number>;
|
||||||
userLabels: UserLabelsData;
|
userLabels: UserLabelsData;
|
||||||
userLabelsToRemove: UserLabelsData;
|
userLabelsToRemove: UserLabelsData;
|
||||||
};
|
};
|
||||||
|
@ -38,15 +38,15 @@ class App extends Component<Props, State> {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
hasUnsavedChanges: false,
|
|
||||||
newLabelUsername: "",
|
newLabelUsername: "",
|
||||||
|
unsavedUserLabelIds: new Set(),
|
||||||
userLabels: props.userLabels,
|
userLabels: props.userLabels,
|
||||||
userLabelsToRemove: [],
|
userLabelsToRemove: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
addNewLabel = async () => {
|
addNewLabel = async () => {
|
||||||
const {newLabelUsername, userLabels} = this.state;
|
const {newLabelUsername, unsavedUserLabelIds, userLabels} = this.state;
|
||||||
if (!isValidTildesUsername(newLabelUsername)) {
|
if (!isValidTildesUsername(newLabelUsername)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,8 @@ class App extends Component<Props, State> {
|
||||||
username: existingUserLabel?.value.username ?? newLabelUsername,
|
username: existingUserLabel?.value.username ?? newLabelUsername,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
this.setState({userLabels});
|
unsavedUserLabelIds.add(id);
|
||||||
|
this.setState({unsavedUserLabelIds, userLabels});
|
||||||
};
|
};
|
||||||
|
|
||||||
onNewUsernameInput = (event: Event) => {
|
onNewUsernameInput = (event: Event) => {
|
||||||
|
@ -79,6 +80,7 @@ class App extends Component<Props, State> {
|
||||||
};
|
};
|
||||||
|
|
||||||
editUserLabel = (event: Event, targetId: number, key: keyof UserLabel) => {
|
editUserLabel = (event: Event, targetId: number, key: keyof UserLabel) => {
|
||||||
|
const {unsavedUserLabelIds} = this.state;
|
||||||
const index = this.state.userLabels.findIndex(
|
const index = this.state.userLabels.findIndex(
|
||||||
({value: {id}}) => id === targetId,
|
({value: {id}}) => id === targetId,
|
||||||
);
|
);
|
||||||
|
@ -95,19 +97,21 @@ class App extends Component<Props, State> {
|
||||||
this.state.userLabels[index].value[key] = newValue;
|
this.state.userLabels[index].value[key] = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsavedUserLabelIds.add(targetId);
|
||||||
this.setState({
|
this.setState({
|
||||||
hasUnsavedChanges: true,
|
unsavedUserLabelIds,
|
||||||
userLabels: this.state.userLabels,
|
userLabels: this.state.userLabels,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
removeUserLabel = async (targetId: number) => {
|
removeUserLabel = async (targetId: number) => {
|
||||||
const {userLabels, userLabelsToRemove} = this.state;
|
const {unsavedUserLabelIds, userLabels, userLabelsToRemove} = this.state;
|
||||||
const index = userLabels.findIndex(({value}) => value.id === targetId);
|
const index = userLabels.findIndex(({value}) => value.id === targetId);
|
||||||
userLabelsToRemove.push(...userLabels.splice(index, 1));
|
userLabelsToRemove.push(...userLabels.splice(index, 1));
|
||||||
|
unsavedUserLabelIds.add(targetId);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
hasUnsavedChanges: true,
|
unsavedUserLabelIds,
|
||||||
userLabels,
|
userLabels,
|
||||||
userLabelsToRemove,
|
userLabelsToRemove,
|
||||||
});
|
});
|
||||||
|
@ -120,11 +124,11 @@ class App extends Component<Props, State> {
|
||||||
|
|
||||||
this.props.userLabels = this.state.userLabels;
|
this.props.userLabels = this.state.userLabels;
|
||||||
void saveUserLabels(this.props.userLabels);
|
void saveUserLabels(this.props.userLabels);
|
||||||
this.setState({hasUnsavedChanges: false, userLabelsToRemove: []});
|
this.setState({unsavedUserLabelIds: new Set(), userLabelsToRemove: []});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {hasUnsavedChanges, newLabelUsername, userLabels} = this.state;
|
const {newLabelUsername, unsavedUserLabelIds, userLabels} = this.state;
|
||||||
userLabels.sort((a, b) => a.value.username.localeCompare(b.value.username));
|
userLabels.sort((a, b) => a.value.username.localeCompare(b.value.username));
|
||||||
|
|
||||||
const labelGroups = new Map<string, UserLabel[]>();
|
const labelGroups = new Map<string, UserLabel[]>();
|
||||||
|
@ -167,8 +171,9 @@ class App extends Component<Props, State> {
|
||||||
await this.removeUserLabel(label.id);
|
await this.removeUserLabel(label.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hasUnsavedChanges = unsavedUserLabelIds.has(label.id);
|
||||||
userLabels.push(
|
userLabels.push(
|
||||||
<li key={label.id}>
|
<li class={hasUnsavedChanges ? "unsaved-changes" : ""} key={label.id}>
|
||||||
<div>
|
<div>
|
||||||
{index === 0 ? <label>Text</label> : undefined}
|
{index === 0 ? <label>Text</label> : undefined}
|
||||||
<input
|
<input
|
||||||
|
@ -217,6 +222,7 @@ class App extends Component<Props, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const anyUnsavedChanges = unsavedUserLabelIds.size > 0;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<header class="page-header">
|
<header class="page-header">
|
||||||
|
@ -249,8 +255,13 @@ class App extends Component<Props, State> {
|
||||||
Add New Label
|
Add New Label
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="button" onClick={this.saveUserLabels}>
|
<button
|
||||||
Save All Changes{hasUnsavedChanges ? "*" : ""}
|
class={`save-button button ${
|
||||||
|
anyUnsavedChanges ? "unsaved-changes" : ""
|
||||||
|
}`}
|
||||||
|
onClick={this.saveUserLabels}
|
||||||
|
>
|
||||||
|
Save All Changes{anyUnsavedChanges ? "*" : ""}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="groups">{labels}</div>
|
<div class="groups">{labels}</div>
|
||||||
|
|
|
@ -1,15 +1,25 @@
|
||||||
@import "button";
|
@import "button";
|
||||||
|
|
||||||
.user-label-editor {
|
.user-label-editor {
|
||||||
|
--save-status-color: var(--blue);
|
||||||
|
|
||||||
|
.unsaved-changes {
|
||||||
|
--save-status-color: var(--yellow);
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
background-color: var(--background-primary);
|
background-color: var(--background-primary);
|
||||||
border: 1px solid var(--blue);
|
border: 1px solid var(--save-status-color);
|
||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
@include button;
|
@include button;
|
||||||
|
|
||||||
|
&.save-button {
|
||||||
|
--button-color: var(--save-status-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
|
|
Loading…
Reference in New Issue