Save visible info blocks to database

And connect to UI elements

Signed-off-by: Marcel Robitaille <mail@marcelrobitaille.me>
This commit is contained in:
Marcel Robitaille 2022-12-29 12:02:33 -04:00 коммит произвёл Christian Wolf
Родитель fdf2b1e53c
Коммит a12586047c
5 изменённых файлов: 118 добавлений и 1 удалений

Просмотреть файл

@ -31,6 +31,8 @@ class ConfigImplementation {
$this->userFolder = $userFolder;
}
protected const KEY_VISIBLE_INFO_BLOCKS = 'visibleInfoBlocks';
/**
* Get the current configuration of the app
*
@ -43,6 +45,7 @@ class ConfigImplementation {
'folder' => $this->userFolder->getPath(),
'update_interval' => $this->dbCacheService->getSearchIndexUpdateInterval(),
'print_image' => $this->service->getPrintImage(),
self::KEY_VISIBLE_INFO_BLOCKS => $this->service->getVisibleInfoBlocks(),
], Http::STATUS_OK);
}
@ -72,6 +75,10 @@ class ConfigImplementation {
$this->service->setPrintImage((bool)$data['print_image']);
}
if (isset($data[self::KEY_VISIBLE_INFO_BLOCKS])) {
$this->service->setVisibleInfoBlocks($data[self::KEY_VISIBLE_INFO_BLOCKS]);
}
$this->dbCacheService->triggerCheck();
return new JSONResponse('OK', Http::STATUS_OK);

Просмотреть файл

@ -39,6 +39,7 @@ class UserConfigHelper {
protected const KEY_LAST_INDEX_UPDATE = 'last_index_update';
protected const KEY_UPDATE_INTERVAL = 'update_interval';
protected const KEY_PRINT_IMAGE = 'print_image';
protected const KEY_VISIBLE_INFO_BLOCKS = 'visible_info_blocks';
protected const KEY_FOLDER = 'folder';
/**
@ -154,6 +155,38 @@ class UserConfigHelper {
}
}
/**
* Determines which info blocks are displayed next to the recipe
*
* @return array<string, bool> keys: info block ids, values: display state
* @throws UserNotLoggedInException if no user is logged in
*/
public function getVisibleInfoBlocks(): array {
$rawValue = $this->getRawValue(self::KEY_VISIBLE_INFO_BLOCKS);
if ($rawValue === '') {
return [
'preparation-time' => true,
'cooking-time' => true,
'total-time' => true,
'nutrition-information' => true,
'tools' => true,
];
}
return json_decode($rawValue, true);
}
/**
* Sets which info blocks are displayed next to the recipe
*
* @param array<string, bool> keys: info block ids, values: display state
* @throws UserNotLoggedInException if no user is logged in
*/
public function setVisibleInfoBlocks(array $visibleInfoBlocks): void {
$this->setRawValue(self::KEY_VISIBLE_INFO_BLOCKS, json_encode($visibleInfoBlocks));
}
/**
* Get the name of the default cookbook.
*

Просмотреть файл

@ -515,6 +515,22 @@ class RecipeService {
return $this->userConfigHelper->getPrintImage();
}
/**
* Sets which info blocks are displayed next to the recipe
* @param array<string, bool> keys: info block ids, values: display state
*/
public function setVisibleInfoBlocks(array $visibleInfoBlocks) {
$this->userConfigHelper->setVisibleInfoBlocks($visibleInfoBlocks);
}
/**
* Determines which info blocks are displayed next to the recipe
* @return array<string, bool> keys: info block ids, values: display state
*/
public function getVisibleInfoBlocks(): array {
return $this->userConfigHelper->getVisibleInfoBlocks();
}
/**
* Get recipe file contents as an array
*

Просмотреть файл

@ -88,14 +88,18 @@
>
<fieldset>
<legend class="settings-info-blocks__legend">
Control which blocks of information are shown in the recipe view. If you do not use some features and find them distracting, you may hide them.
Control which blocks of information are shown in the recipe
view. If you do not use some features and find them
distracting, you may hide them.
</legend>
<ul>
<li>
<input
id="info-blocks-checkbox-preparation-time"
v-model="visibleInfoBlocks"
type="checkbox"
class="checkbox"
value="preparation-time"
/>
<label for="info-blocks-checkbox-preparation-time">
{{ t("cookbook", "Preparation time") }}
@ -104,8 +108,10 @@
<li>
<input
id="info-blocks-checkbox-cooking-time"
v-model="visibleInfoBlocks"
type="checkbox"
class="checkbox"
value="cooking-time"
/>
<label for="info-blocks-checkbox-cooking-time">
{{ t("cookbook", "Cooking time") }}
@ -114,8 +120,10 @@
<li>
<input
id="info-blocks-checkbox-total-time"
v-model="visibleInfoBlocks"
type="checkbox"
class="checkbox"
value="total-time"
/>
<label for="info-blocks-checkbox-total-time">
{{ t("cookbook", "Total time") }}
@ -124,8 +132,10 @@
<li>
<input
id="info-blocks-checkbox-nutrition-information"
v-model="visibleInfoBlocks"
type="checkbox"
class="checkbox"
value="nutrition-information"
/>
<label for="info-blocks-checkbox-nutrition-information">
{{ t("cookbook", "Nutrition information") }}
@ -134,8 +144,10 @@
<li>
<input
id="info-blocks-checkbox-tools"
v-model="visibleInfoBlocks"
type="checkbox"
class="checkbox"
value="tools"
/>
<label for="info-blocks-checkbox-tools">
{{ t("cookbook", "Tools") }}
@ -161,6 +173,23 @@ import { showSimpleAlertModal } from "cookbook/js/modals"
export const SHOW_SETTINGS_EVENT = "show-settings"
const INFO_BLOCK_KEYS = [
"preparation-time",
"cooking-time",
"total-time",
"nutrition-information",
"tools",
]
// The Vue representation of multiple checkboxes is an array of all checked values
// However, the backend representation is an object (map of block ids to booleans)
const visibleInfoBlocksEncode = (arr) =>
Object.fromEntries(INFO_BLOCK_KEYS.map((key) => [key, arr.includes(key)]))
const visibleInfoBlocksDecode = (obj) =>
Object.entries(obj)
.filter(([, v]) => v)
.map(([k]) => k)
export default {
name: "SettingsDialog",
components: {
@ -183,6 +212,8 @@ export default {
// (the one when config is loaded at page load)
resetInterval: true,
updateInterval: 0,
visibleInfoBlocks: [...INFO_BLOCK_KEYS],
resetVisibleInfoBlocks: true,
}
},
watch: {
@ -232,6 +263,26 @@ export default {
this.updateInterval = oldVal
}
},
async visibleInfoBlocks(newVal, oldVal) {
// Avoid infinite loop on page load and when reseting value after failed submit
if (this.resetVisibleInfoBlocks) {
this.resetVisibleInfoBlocks = false
return
}
try {
const data = visibleInfoBlocksEncode(newVal)
await api.config.visibleInfoBlocks.update(data)
// Should this check the response of the query? To catch some errors that redirect the page
} catch (err) {
// eslint-disable-next-line no-console
console.error("Error while trying to save info blocks", err)
await showSimpleAlertModal(
t("cookbook", "Could save visible info blocks")
)
this.resetVisibleInfoBlocks = true
this.visibleInfoBlocks = oldVal
}
},
},
mounted() {
this.setup()
@ -290,6 +341,9 @@ export default {
}
this.printImage = config.print_image
this.visibleInfoBlocks = visibleInfoBlocksDecode(
config.visibleInfoBlocks
)
this.showTagCloudInRecipeList =
this.$store.state.localSettings.showTagCloudInRecipeList
this.updateInterval = config.update_interval

Просмотреть файл

@ -90,6 +90,10 @@ function updateRecipeDirectory(newDir) {
return instance.post(`${baseUrl}/config`, { folder: newDir })
}
function updateVisibleInfoBlocks(visibleInfoBlocks) {
return instance.post(`${baseUrl}/config`, { visibleInfoBlocks })
}
function reindex() {
return instance.post(`${baseUrl}/reindex`)
}
@ -125,5 +129,8 @@ export default {
updateInterval: {
update: updateUpdateInterval,
},
visibleInfoBlocks: {
update: updateVisibleInfoBlocks,
},
},
}