2021-05-24 03:03:26 +00:00
|
|
|
import React, { useCallback, useContext, useState } from "react"
|
2021-05-25 02:39:48 +00:00
|
|
|
import ContextConditionEditor from "../../contexts/ContextConditionEditor"
|
2021-04-29 14:58:31 +00:00
|
|
|
import useArrayState from "../../hooks/useArrayState"
|
2021-05-07 15:41:25 +00:00
|
|
|
import Style from "./RepositoryEditor.module.css"
|
2021-05-22 02:57:38 +00:00
|
|
|
import BoxConditionLocation from "../interactive/BoxConditionLocation"
|
2021-05-07 15:41:25 +00:00
|
|
|
import BoxConditionHashtag from "../interactive/BoxConditionHashtag"
|
|
|
|
import BoxConditionUser from "../interactive/BoxConditionUser"
|
|
|
|
import BoxConditionDatetime from "../interactive/BoxConditionDatetime"
|
|
|
|
import BoxConditions from "../interactive/BoxConditions"
|
|
|
|
import BoxRepositoryCreate from "../interactive/BoxRepositoryCreate"
|
|
|
|
import classNames from "classnames"
|
2021-05-07 23:40:49 +00:00
|
|
|
import ContextUser from "../../contexts/ContextUser"
|
2021-05-24 03:02:07 +00:00
|
|
|
import { Condition } from "../../objects/Condition"
|
|
|
|
import useBackendViewset from "../../hooks/useBackendViewset"
|
|
|
|
import { Redirect } from "react-router"
|
2021-04-29 02:28:33 +00:00
|
|
|
|
|
|
|
|
2021-05-07 01:44:05 +00:00
|
|
|
export default function RepositoryEditor({
|
2021-05-11 14:37:15 +00:00
|
|
|
id = null,
|
|
|
|
name,
|
|
|
|
is_active: isActive,
|
|
|
|
start,
|
|
|
|
end,
|
|
|
|
conditions,
|
|
|
|
evaluation_mode: evaluationMode,
|
|
|
|
className,
|
|
|
|
}) {
|
2021-05-24 03:02:07 +00:00
|
|
|
/** The currently logged in user. */
|
|
|
|
const { user } = useContext(ContextUser)
|
|
|
|
|
2021-05-07 01:44:05 +00:00
|
|
|
/** The repository name. */
|
2021-05-10 15:24:32 +00:00
|
|
|
const [_name, setName] = useState(name ?? "")
|
2021-05-07 01:44:05 +00:00
|
|
|
|
|
|
|
/** The conditions of the data gathering. */
|
2021-05-30 14:46:21 +00:00
|
|
|
const parsedConditions = conditions.map(cond => Condition.fromRaw(cond))
|
2021-04-29 03:03:58 +00:00
|
|
|
const {
|
2021-05-30 14:46:21 +00:00
|
|
|
value: _conditions,
|
2021-05-07 02:48:25 +00:00
|
|
|
setValue: setRawConditions,
|
|
|
|
appendValue: appendRawCondition,
|
|
|
|
removeValue: removeRawCondition,
|
|
|
|
spliceValue: spliceRawCondition,
|
2021-05-30 14:46:21 +00:00
|
|
|
} = useArrayState(parsedConditions)
|
2021-04-29 02:28:33 +00:00
|
|
|
|
2021-05-07 01:44:05 +00:00
|
|
|
/** The operator the conditions should be evaluated with. */
|
2021-05-07 23:40:49 +00:00
|
|
|
const [_evaluationMode, setEvaluationMode] = useState(evaluationMode ?? 0)
|
|
|
|
|
2021-05-24 03:02:07 +00:00
|
|
|
/** The backend viewset to use to create / edit the repository. */
|
|
|
|
const {running, error, createResource, editResource} = useBackendViewset(
|
|
|
|
`/api/v1/repositories/`,
|
|
|
|
"id",
|
|
|
|
{
|
|
|
|
list: false,
|
|
|
|
create: true,
|
|
|
|
retrieve: false,
|
|
|
|
edit: true,
|
|
|
|
destroy: false,
|
|
|
|
command: false,
|
|
|
|
action: false,
|
|
|
|
}
|
|
|
|
)
|
2021-05-07 23:40:49 +00:00
|
|
|
|
2021-05-24 03:02:07 +00:00
|
|
|
/** If `true`, switches to the repository page on the next render. */
|
|
|
|
const [switchPage, setSwitchPage] = useState(false)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Save the current changes, creating or editing it as needed.
|
|
|
|
*/
|
|
|
|
const save = useCallback(
|
|
|
|
async () => {
|
|
|
|
const body = {
|
2021-05-11 16:05:01 +00:00
|
|
|
"id": id,
|
|
|
|
"name": _name,
|
2021-05-11 17:42:04 +00:00
|
|
|
"start": null,
|
2021-05-24 03:02:07 +00:00
|
|
|
"is_active": true,
|
|
|
|
"end": null,
|
|
|
|
"owner": user,
|
|
|
|
"spectators": null,
|
|
|
|
"evaluation_mode": _evaluationMode,
|
|
|
|
"conditions": _conditions,
|
2021-05-11 16:05:01 +00:00
|
|
|
}
|
2021-05-07 01:44:05 +00:00
|
|
|
|
2021-05-11 16:05:01 +00:00
|
|
|
if(!id) {
|
2021-05-24 03:02:07 +00:00
|
|
|
console.info("Creating new repository with body: ", body)
|
|
|
|
await createResource(body)
|
2021-05-07 01:44:05 +00:00
|
|
|
}
|
|
|
|
else {
|
2021-05-24 03:02:07 +00:00
|
|
|
console.info("Editing repository ", id, " with body: ", body)
|
|
|
|
await editResource(id, body)
|
2021-05-07 01:44:05 +00:00
|
|
|
}
|
2021-05-24 03:02:07 +00:00
|
|
|
setSwitchPage(true)
|
2021-05-07 01:44:05 +00:00
|
|
|
},
|
2021-05-24 03:02:07 +00:00
|
|
|
[id, createResource, editResource, _conditions, _evaluationMode, _name, user],
|
2021-05-07 01:44:05 +00:00
|
|
|
)
|
|
|
|
|
2021-05-07 23:40:49 +00:00
|
|
|
|
2021-05-07 01:44:05 +00:00
|
|
|
/**
|
|
|
|
* Cancel the changes made so far to the repository.
|
|
|
|
*/
|
|
|
|
const revert = useCallback(
|
|
|
|
() => {
|
|
|
|
setName(name)
|
2021-05-07 02:48:25 +00:00
|
|
|
setRawConditions(conditions)
|
2021-05-07 01:44:05 +00:00
|
|
|
setEvaluationMode(evaluationMode)
|
|
|
|
},
|
2021-05-11 16:05:01 +00:00
|
|
|
[name, isActive, start, end, conditions, evaluationMode, setRawConditions],
|
2021-05-07 01:44:05 +00:00
|
|
|
)
|
|
|
|
|
2021-05-07 02:48:25 +00:00
|
|
|
/**
|
|
|
|
* Try to add a new condition, logging a message to the console if something goes wrong.
|
|
|
|
*/
|
|
|
|
const addCondition = useCallback(
|
|
|
|
(newCond) => {
|
|
|
|
|
|
|
|
// Check for duplicates
|
2021-05-11 14:37:15 +00:00
|
|
|
let duplicate = null
|
2021-05-07 02:48:25 +00:00
|
|
|
for(const oldCond of _conditions) {
|
|
|
|
if(newCond.type === oldCond.type && newCond.content === oldCond.content) {
|
|
|
|
duplicate = oldCond
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(duplicate) {
|
2021-05-24 03:02:07 +00:00
|
|
|
console.debug("Cannot add ", newCond, ": ", duplicate, " already exists.")
|
2021-05-07 02:48:25 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-05-24 03:02:07 +00:00
|
|
|
console.debug("Adding ", newCond, " to the repository conditions")
|
2021-05-07 02:48:25 +00:00
|
|
|
appendRawCondition(newCond)
|
|
|
|
},
|
2021-05-11 16:05:01 +00:00
|
|
|
[_conditions, appendRawCondition],
|
2021-05-07 02:48:25 +00:00
|
|
|
)
|
|
|
|
|
2021-05-24 03:02:07 +00:00
|
|
|
// Hack to switch page on success
|
|
|
|
if(!error && switchPage) {
|
|
|
|
return <Redirect to={"/repositories"}/>
|
|
|
|
}
|
|
|
|
|
2021-04-29 02:28:33 +00:00
|
|
|
return (
|
2021-05-25 02:39:48 +00:00
|
|
|
<ContextConditionEditor.Provider
|
2021-05-11 14:37:15 +00:00
|
|
|
value={{
|
|
|
|
conditions: _conditions, addCondition, appendRawCondition, removeRawCondition, spliceRawCondition,
|
|
|
|
}}
|
|
|
|
>
|
2021-05-07 15:41:25 +00:00
|
|
|
<div className={classNames(Style.RepositoryEditor, className)}>
|
2021-05-22 02:57:38 +00:00
|
|
|
<BoxConditionLocation className={Style.SearchByZone}/>
|
2021-05-07 15:41:25 +00:00
|
|
|
<BoxConditionHashtag className={Style.SearchByHashtags}/>
|
|
|
|
<BoxConditionUser className={Style.SearchByUser}/>
|
|
|
|
<BoxConditionDatetime className={Style.SearchByTimePeriod}/>
|
|
|
|
<BoxConditions className={Style.Conditions}/>
|
2021-05-25 02:39:48 +00:00
|
|
|
<BoxRepositoryCreate
|
|
|
|
className={Style.CreateDialog}
|
2021-05-25 02:41:49 +00:00
|
|
|
id={id}
|
|
|
|
name={_name}
|
2021-05-25 02:39:48 +00:00
|
|
|
setName={setName}
|
|
|
|
evaluationMode={_evaluationMode}
|
|
|
|
setEvaluationMode={setEvaluationMode}
|
|
|
|
running={running}
|
|
|
|
error={error}
|
|
|
|
revert={revert}
|
|
|
|
save={save}
|
|
|
|
/>
|
2021-05-07 15:41:25 +00:00
|
|
|
</div>
|
2021-05-25 02:39:48 +00:00
|
|
|
</ContextConditionEditor.Provider>
|
2021-04-29 02:28:33 +00:00
|
|
|
)
|
|
|
|
}
|