Browse Source

Added option to pin new apps/categories by default

unknown 4 years ago
parent
commit
8b87ad92f1

+ 38 - 4
client/src/components/Settings/OtherSettings/OtherSettings.tsx

@@ -9,6 +9,8 @@ import { ApiResponse, Config, NewNotification } from '../../../interfaces';
 
 interface FormState {
   customTitle: string;
+  pinAppsByDefault: number;
+  pinCategoriesByDefault: number;
 }
 
 interface ComponentProps {
@@ -17,12 +19,14 @@ interface ComponentProps {
 
 const OtherSettings = (props: ComponentProps): JSX.Element => {
   const [formData, setFormData] = useState<FormState>({
-    customTitle: document.title
+    customTitle: document.title,
+    pinAppsByDefault: 0,
+    pinCategoriesByDefault: 0
   })
 
   // get initial config
   useEffect(() => {
-    axios.get<ApiResponse<Config[]>>('/api/config?keys=customTitle')
+    axios.get<ApiResponse<Config[]>>('/api/config?keys=customTitle,pinAppsByDefault,pinCategoriesByDefault')
       .then(data => {
         let tmpFormData = { ...formData };
 
@@ -60,10 +64,16 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
     document.title = formData.customTitle;
   }
 
-  const inputChangeHandler = (e: ChangeEvent<HTMLInputElement>) => {
+  const inputChangeHandler = (e: ChangeEvent<HTMLInputElement | HTMLSelectElement>, isNumber?: boolean) => {
+    let value: string | number = e.target.value;
+
+    if (isNumber) {
+      value = parseFloat(value);
+    }
+
     setFormData({
       ...formData,
-      [e.target.name]: e.target.value
+      [e.target.name]: value
     })
   }
 
@@ -80,6 +90,30 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
           onChange={(e) => inputChangeHandler(e)}
         />
       </InputGroup>
+      <InputGroup>
+        <label htmlFor='pinAppsByDefault'>Pin new applications by default</label>
+        <select
+          id='pinAppsByDefault'
+          name='pinAppsByDefault'
+          value={formData.pinAppsByDefault}
+          onChange={(e) => inputChangeHandler(e, true)}
+        >
+          <option value={1}>True</option>
+          <option value={0}>False</option>
+        </select>
+      </InputGroup>
+      <InputGroup>
+        <label htmlFor='pinCategoriesByDefault'>Pin new categories by default</label>
+        <select
+          id='pinCategoriesByDefault'
+          name='pinCategoriesByDefault'
+          value={formData.pinCategoriesByDefault}
+          onChange={(e) => inputChangeHandler(e, true)}
+        >
+          <option value={1}>True</option>
+          <option value={0}>False</option>
+        </select>
+      </InputGroup>
     <Button>Save changes</Button>
     </form>
   )

+ 18 - 1
controllers/apps.js

@@ -1,12 +1,29 @@
 const asyncWrapper = require('../middleware/asyncWrapper');
 const ErrorResponse = require('../utils/ErrorResponse');
 const App = require('../models/App');
+const Config = require('../models/Config');
 
 // @desc      Create new app
 // @route     POST /api/apps
 // @access    Public
 exports.createApp = asyncWrapper(async (req, res, next) => {
-  const app = await App.create(req.body);
+  // Get config from database
+  const pinApps = await Config.findOne({
+    where: { key: 'pinAppsByDefault' }
+  });
+
+  let app;
+
+  if (pinApps) {
+    if (parseInt(pinApps.value)) {
+      app = await App.create({
+        ...req.body,
+        isPinned: true
+      })
+    } else {
+      app = await App.create(req.body);
+    }
+  }
 
   res.status(201).json({
     success: true,

+ 18 - 1
controllers/category.js

@@ -2,12 +2,29 @@ const asyncWrapper = require('../middleware/asyncWrapper');
 const ErrorResponse = require('../utils/ErrorResponse');
 const Category = require('../models/Category');
 const Bookmark = require('../models/Bookmark');
+const Config = require('../models/Config');
 
 // @desc      Create new category
 // @route     POST /api/categories
 // @access    Public
 exports.createCategory = asyncWrapper(async (req, res, next) => {
-  const category = await Category.create(req.body);
+  // Get config from database
+  const pinCategories = await Config.findOne({
+    where: { key: 'pinCategoriesByDefault' }
+  });
+
+  let category;
+
+  if (pinCategories) {
+    if (parseInt(pinCategories.value)) {
+      category = await Category.create({
+        ...req.body,
+        isPinned: true
+      })
+    } else {
+      category = await Category.create(req.body);
+    }
+  }
 
   res.status(201).json({
     success: true,

+ 5 - 8
utils/initConfig.js

@@ -1,16 +1,13 @@
 const { Op } = require('sequelize');
 const Config = require('../models/Config');
+const { config } = require('./initialConfig.json');
 
 const initConfig = async () => {
-  // Config keys
-  const keys = ['WEATHER_API_KEY', 'lat', 'long', 'isCelsius', 'customTitle'];
-  const values = ['', 0, 0, true, 'Flame'];
-
   // Get config values
   const configPairs = await Config.findAll({
     where: {
       key: {
-        [Op.or]: keys
+        [Op.or]: config.map(pair => pair.key)
       }
     }
   })
@@ -19,12 +16,12 @@ const initConfig = async () => {
   const configKeys = configPairs.map((pair) => pair.key);
 
   // Create missing pairs
-  keys.forEach(async (key, idx) => {
+  config.forEach(async ({ key, value}) => {
     if (!configKeys.includes(key)) {
       await Config.create({
         key,
-        value: values[idx],
-        valueType: typeof values[idx]
+        value,
+        valueType: typeof value
       })
     }
   })

+ 32 - 0
utils/initialConfig.json

@@ -0,0 +1,32 @@
+{
+  "config": [
+    {
+      "key": "WEATHER_API_KEY",
+      "value": ""
+    },
+    {
+      "key": "lat",
+      "value": 0
+    },
+    {
+      "key": "long",
+      "value": 0
+    },
+    {
+      "key": "isCelsius",
+      "value": true
+    },
+    {
+      "key": "customTitle",
+      "value": "Flame"
+    },
+    {
+      "key": "pinAppsByDefault",
+      "value": true
+    },
+    {
+      "key": "pinCategoriesByDefault",
+      "value": true
+    }
+  ]
+}