replace without confirming

pull/2092/head
filip mertens 3 years ago
parent 6bc2c5523e
commit b9b5d4c6d1
  1. 4
      libs/remix-ui/app/src/lib/remix-app/components/modals/modal-wrapper.tsx
  2. 10
      libs/remix-ui/app/src/lib/remix-app/context/provider.tsx
  3. 3
      libs/remix-ui/app/src/lib/remix-app/interface/index.ts
  4. 3
      libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts
  5. 3
      libs/remix-ui/modal-dialog/src/lib/types/index.ts
  6. 33
      libs/remix-ui/search/src/lib/components/OverWriteCheck.tsx
  7. 2
      libs/remix-ui/search/src/lib/components/Search.tsx
  8. 13
      libs/remix-ui/search/src/lib/components/results/ResultItem.tsx
  9. 12
      libs/remix-ui/search/src/lib/components/results/ResultSummary.tsx
  10. 25
      libs/remix-ui/search/src/lib/context/context.tsx
  11. 15
      libs/remix-ui/search/src/lib/reducers/Reducer.ts
  12. 7
      libs/remix-ui/search/src/lib/types/index.ts

@ -10,6 +10,7 @@ interface ModalWrapperProps extends ModalDialogProps {
const ModalWrapper = (props: ModalWrapperProps) => { const ModalWrapper = (props: ModalWrapperProps) => {
const [state, setState] = useState<ModalDialogProps>() const [state, setState] = useState<ModalDialogProps>()
const ref = useRef() const ref = useRef()
const data = useRef()
const onFinishPrompt = async () => { const onFinishPrompt = async () => {
if (ref.current === undefined) { if (ref.current === undefined) {
@ -21,7 +22,7 @@ const ModalWrapper = (props: ModalWrapperProps) => {
} }
const onOkFn = async () => { const onOkFn = async () => {
(props.okFn) ? props.okFn() : props.resolve(true) (props.okFn) ? props.okFn(data.current) : props.resolve(data.current || true)
} }
const onCancelFn = async () => { const onCancelFn = async () => {
@ -37,6 +38,7 @@ const ModalWrapper = (props: ModalWrapperProps) => {
} }
useEffect(() => { useEffect(() => {
data.current = props.data
if (props.modalType) { if (props.modalType) {
switch (props.modalType) { switch (props.modalType) {
case ModalTypes.prompt: case ModalTypes.prompt:

@ -15,18 +15,18 @@ export const ModalProvider = ({ children = [], reducer = modalReducer, initialSt
}) })
} }
const modal = (data: AppModal) => { const modal = (modalData: AppModal) => {
const { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType, defaultValue, hideFn } = data const { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType, defaultValue, hideFn, data } = modalData
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
dispatch({ dispatch({
type: modalActionTypes.setModal, type: modalActionTypes.setModal,
payload: { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType: modalType || ModalTypes.default, defaultValue: defaultValue, hideFn, resolve, next: onNextFn } payload: { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType: modalType || ModalTypes.default, defaultValue: defaultValue, hideFn, resolve, next: onNextFn, data }
}) })
}) })
} }
const alert = (data: AlertModal) => { const alert = (modalData: AlertModal) => {
return modal({ id: data.id, title: data.title || 'Alert', message: data.message || data.title, okLabel: 'OK', okFn: (value?:any) => {}, cancelLabel: '', cancelFn: () => {} }) return modal({ id: modalData.id, title: modalData.title || 'Alert', message: modalData.message || modalData.title, okLabel: 'OK', okFn: (value?:any) => {}, cancelLabel: '', cancelFn: () => {} })
} }
const handleHideModal = () => { const handleHideModal = () => {

@ -15,7 +15,8 @@ export interface AppModal {
defaultValue?: string defaultValue?: string
hideFn?: () => void, hideFn?: () => void,
resolve?: (value?:any) => void, resolve?: (value?:any) => void,
next?: () => void next?: () => void,
data?: any
} }
export interface AlertModal { export interface AlertModal {

@ -20,7 +20,8 @@ export const modalReducer = (state: ModalState = ModalInitialState, action: Moda
defaultValue: action.payload.defaultValue, defaultValue: action.payload.defaultValue,
hideFn: action.payload.hideFn, hideFn: action.payload.hideFn,
resolve: action.payload.resolve, resolve: action.payload.resolve,
next: action.payload.next next: action.payload.next,
data: action.payload.data
} }
const modalList: AppModal[] = state.modals.slice() const modalList: AppModal[] = state.modals.slice()

@ -14,5 +14,6 @@ export interface ModalDialogProps {
handleHide: (hideState?: boolean) => void, handleHide: (hideState?: boolean) => void,
children?: React.ReactNode, children?: React.ReactNode,
resolve?: (value?:any) => void, resolve?: (value?:any) => void,
next?: () => void next?: () => void,
data?: any
} }

@ -0,0 +1,33 @@
import React, { useContext, useEffect, useRef, useState } from 'react'
import { SearchContext } from '../context/context'
export const OverWriteCheck = props => {
const { setReplaceWithoutConfirmation } = useContext(SearchContext)
const change = e => {
console.log(e.target.checked)
setReplaceWithoutConfirmation(e.target.checked)
}
return (
<>
<div className="find-part">
<div className="mb-2 remixui_nightlyBuilds custom-control custom-checkbox">
<input
className="mr-2 custom-control-input"
id="confirm_replace"
type="checkbox"
onChange={change}
/>
<label
htmlFor='confirm_replace'
data-id="compilerNightliesBuild"
className="form-check-label custom-control-label"
>
replace without confirmation
</label>
</div>
</div>
</>
)
}

@ -6,6 +6,7 @@ import '../search.css'
import { Include } from './Include' import { Include } from './Include'
import { Exclude } from './Exclude' import { Exclude } from './Exclude'
import { Replace } from './Replace' import { Replace } from './Replace'
import { OverWriteCheck } from './OverWriteCheck'
export const SearchTab = props => { export const SearchTab = props => {
@ -19,6 +20,7 @@ return (
<Replace></Replace> <Replace></Replace>
<Include></Include> <Include></Include>
<Exclude></Exclude> <Exclude></Exclude>
<OverWriteCheck></OverWriteCheck>
<Results></Results> <Results></Results>
</SearchProvider> </SearchProvider>
</div> </div>

@ -1,4 +1,4 @@
import React, { useContext, useEffect, useState } from 'react' import React, { useContext, useEffect, useRef, useState } from 'react'
import { SearchContext } from '../../context/context' import { SearchContext } from '../../context/context'
import { SearchResult, SearchResultLine } from '../../types' import { SearchResult, SearchResultLine } from '../../types'
import { ResultFileName } from './ResultFileName' import { ResultFileName } from './ResultFileName'
@ -9,15 +9,23 @@ interface ResultItemProps {
} }
export const ResultItem = (props: ResultItemProps) => { export const ResultItem = (props: ResultItemProps) => {
const { state, findText } = useContext(SearchContext) const { state, findText, disableForceReload } = useContext(SearchContext)
const [loading, setLoading] = useState<boolean>(false) const [loading, setLoading] = useState<boolean>(false)
const [lines, setLines] = useState<SearchResultLine[]>([]) const [lines, setLines] = useState<SearchResultLine[]>([])
const [toggleExpander, setToggleExpander] = useState<boolean>(false) const [toggleExpander, setToggleExpander] = useState<boolean>(false)
const reloadTimeOut = useRef(null)
useEffect(() => { useEffect(() => {
reload() reload()
}, [props.file.timeStamp]) }, [props.file.timeStamp])
useEffect(() => {
if(props.file.forceReload){
clearTimeout(reloadTimeOut.current)
reloadTimeOut.current = setTimeout(() => reload(), 1000)
}
}, [props.file.forceReload])
const toggleClass = () => { const toggleClass = () => {
setToggleExpander(!toggleExpander) setToggleExpander(!toggleExpander)
} }
@ -30,6 +38,7 @@ export const ResultItem = (props: ResultItemProps) => {
findText(props.file.filename).then(res => { findText(props.file.filename).then(res => {
setLines(res) setLines(res)
setLoading(false) setLoading(false)
disableForceReload(props.file.filename)
}) })
} }

@ -1,3 +1,4 @@
import { useDialogDispatchers } from 'libs/remix-ui/app/src/lib/remix-app/context/provider'
import React, { useContext } from 'react' import React, { useContext } from 'react'
import { SearchContext } from '../../context/context' import { SearchContext } from '../../context/context'
import { SearchResult, SearchResultLine, SearchResultLineLine } from '../../types' import { SearchResult, SearchResultLine, SearchResultLineLine } from '../../types'
@ -10,11 +11,12 @@ interface ResultSummaryProps {
export const ResultSummary = (props: ResultSummaryProps) => { export const ResultSummary = (props: ResultSummaryProps) => {
const { hightLightInPath, replaceText, state } = useContext(SearchContext) const { hightLightInPath, replaceText, state } = useContext(SearchContext)
const { modal } = useDialogDispatchers()
const selectLine = async (line: SearchResultLineLine) => { const selectLine = async (line: SearchResultLineLine) => {
await hightLightInPath(props.searchResult, line) await hightLightInPath(props.searchResult, line)
} }
const replace = async (line: SearchResultLineLine) => { const confirmReplace = async (line: SearchResultLineLine) => {
props.setLoading(true) props.setLoading(true)
try{ try{
await replaceText(props.searchResult, line) await replaceText(props.searchResult, line)
@ -23,6 +25,14 @@ export const ResultSummary = (props: ResultSummaryProps) => {
} }
} }
const replace = async (line: SearchResultLineLine) => {
if(state.replaceWithOutConfirmation){
confirmReplace(line)
}else{
modal({ id: 'matomoModal', title: 'Replace', message: `Are you sure you want to replace '${line.center}' by '${state.replace}' in ${props.searchResult.filename}?`, okLabel: 'Yes', okFn: confirmReplace, cancelLabel: 'No', cancelFn: ()=>{}, data: line })
}
}
return ( return (
<> <>
{props.line.lines.map((lineItem, index) => ( {props.line.lines.map((lineItem, index) => (

@ -33,6 +33,8 @@ export interface SearchingStateInterface {
toggleCaseSensitive: () => void toggleCaseSensitive: () => void
toggleMatchWholeWord: () => void toggleMatchWholeWord: () => void
toggleUseRegex: () => void toggleUseRegex: () => void
setReplaceWithoutConfirmation: (value: boolean) => void
disableForceReload: (file: string) => void
} }
export const SearchContext = createContext<SearchingStateInterface>(null) export const SearchContext = createContext<SearchingStateInterface>(null)
@ -120,6 +122,18 @@ export const SearchProvider = ({
payload: undefined payload: undefined
}) })
}, },
setReplaceWithoutConfirmation: (value: boolean) => {
dispatch({
type: 'SET_REPLACE_WITHOUT_CONFIRMATION',
payload: value
})
},
disableForceReload: (file: string) => {
dispatch({
type: 'DISABLE_FORCE_RELOAD',
payload: file
})
},
findText: async (path: string) => { findText: async (path: string) => {
if (!plugin) return if (!plugin) return
try { try {
@ -165,10 +179,12 @@ export const SearchProvider = ({
} }
const reloadStateForFile = async (file: string) => { const reloadStateForFile = async (file: string) => {
clearTimeout(reloadTimeOut.current) //clearTimeout(reloadTimeOut.current)
reloadTimeOut.current = setTimeout(async () => { console.log('reload file', file)
//reloadTimeOut.current = setTimeout(async () => {
console.log('calling file', file)
await value.reloadFile(file) await value.reloadFile(file)
}, 1000) //}, 1000)
} }
useEffect(() => { useEffect(() => {
@ -198,7 +214,8 @@ export const SearchProvider = ({
filename: file, filename: file,
lines: [], lines: [],
path: file, path: file,
timeStamp: Date.now() timeStamp: Date.now(),
forceReload: false
} }
return r return r
}) })

@ -52,10 +52,23 @@ export const SearchReducer = (state: SearchState = SearchingInitialState, action
matchWord: !state.matchWord, matchWord: !state.matchWord,
timeStamp: Date.now() timeStamp: Date.now()
} }
case 'SET_REPLACE_WITHOUT_CONFIRMATION':
return {
...state,
replaceWithOutConfirmation: action.payload,
}
case 'DISABLE_FORCE_RELOAD':
if (state.searchResults) {
const findFile = state.searchResults.find(file => file.filename === action.payload)
if (findFile) findFile.forceReload = false
}
return {
...state,
}
case 'RELOAD_FILE': case 'RELOAD_FILE':
if (state.searchResults) { if (state.searchResults) {
const findFile = state.searchResults.find(file => file.filename === action.payload) const findFile = state.searchResults.find(file => file.filename === action.payload)
if (findFile) findFile.timeStamp = Date.now() if (findFile) findFile.forceReload = true
} }
return { return {
...state, ...state,

@ -29,7 +29,8 @@ export interface SearchResult {
filename: string, filename: string,
path: string, path: string,
lines: SearchResultLine[], lines: SearchResultLine[],
timeStamp: number timeStamp: number,
forceReload: boolean
} }
export interface SearchState { export interface SearchState {
@ -40,8 +41,9 @@ export interface SearchState {
exclude: string, exclude: string,
casesensitive: boolean, casesensitive: boolean,
matchWord: boolean, matchWord: boolean,
replaceWithOutConfirmation: boolean,
useRegExp: boolean, useRegExp: boolean,
timeStamp: number timeStamp: number,
} }
export const SearchingInitialState: SearchState = { export const SearchingInitialState: SearchState = {
@ -53,5 +55,6 @@ export const SearchingInitialState: SearchState = {
casesensitive: false, casesensitive: false,
matchWord: false, matchWord: false,
useRegExp: false, useRegExp: false,
replaceWithOutConfirmation: false,
timeStamp: 0 timeStamp: 0
} }
Loading…
Cancel
Save