1
Fork 0

Add save status changes to the dedicated user label editor.

This commit is contained in:
Bauke 2023-09-15 18:22:13 +02:00
parent 45d9f03b50
commit 7a73aa57c3
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
2 changed files with 34 additions and 13 deletions

View File

@ -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>

View File

@ -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 {