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