diff --git a/package-lock.json b/package-lock.json index 65e380d1..82f290b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,6 +68,7 @@ "@vitejs/plugin-legacy": "~2.1.0", "@vitejs/plugin-vue": "~3.1.0", "@vue/compiler-sfc": "~3.2.36", + "@vuepic/vue-datepicker": "^3.4.8", "aedes": "^0.46.3", "babel-plugin-rewire": "~1.2.0", "bootstrap": "5.1.3", @@ -3941,6 +3942,21 @@ "integrity": "sha512-dTyhTIRmGXBjxJE+skC8tTWCGLCVc4wQgRRLt8+O9p5ewBAjoBwtCAkLPrtToSr1xltoe3st21Pv953aOZ7alg==", "dev": true }, + "node_modules/@vuepic/vue-datepicker": { + "version": "3.4.8", + "resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-3.4.8.tgz", + "integrity": "sha512-nbuMA7IgjtT99LqcjSTSUcl7omTZSB+7vYSWQ9gQm31Frm/1wn54fT1Q0HaRD9nHXX982AACbqeND4K80SKONw==", + "dev": true, + "dependencies": { + "date-fns": "^2.29.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "vue": ">=3.2.0" + } + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -20409,6 +20425,15 @@ "integrity": "sha512-dTyhTIRmGXBjxJE+skC8tTWCGLCVc4wQgRRLt8+O9p5ewBAjoBwtCAkLPrtToSr1xltoe3st21Pv953aOZ7alg==", "dev": true }, + "@vuepic/vue-datepicker": { + "version": "3.4.8", + "resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-3.4.8.tgz", + "integrity": "sha512-nbuMA7IgjtT99LqcjSTSUcl7omTZSB+7vYSWQ9gQm31Frm/1wn54fT1Q0HaRD9nHXX982AACbqeND4K80SKONw==", + "dev": true, + "requires": { + "date-fns": "^2.29.2" + } + }, "abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", diff --git a/package.json b/package.json index 219042aa..01bf7da0 100644 --- a/package.json +++ b/package.json @@ -124,6 +124,7 @@ "@vitejs/plugin-legacy": "~2.1.0", "@vitejs/plugin-vue": "~3.1.0", "@vue/compiler-sfc": "~3.2.36", + "@vuepic/vue-datepicker": "^3.4.8", "aedes": "^0.46.3", "babel-plugin-rewire": "~1.2.0", "bootstrap": "5.1.3", diff --git a/server/model/maintenance.js b/server/model/maintenance.js index 1b0b9ee0..2f3e2000 100644 --- a/server/model/maintenance.js +++ b/server/model/maintenance.js @@ -19,6 +19,8 @@ class Maintenance extends BeanModel { description: this.description, start_date: this.start_date, end_date: this.end_date, + strategy: this.strategy, + active: !!this.active, }; } @@ -27,13 +29,7 @@ class Maintenance extends BeanModel { * @returns {Object} */ async toJSON() { - return { - id: this.id, - title: this.title, - description: this.description, - start_date: this.start_date, - end_date: this.end_date, - }; + return this.toPublicJSON(); } } diff --git a/src/assets/vue-datepicker.scss b/src/assets/vue-datepicker.scss new file mode 100644 index 00000000..dedbc080 --- /dev/null +++ b/src/assets/vue-datepicker.scss @@ -0,0 +1,39 @@ +@import "@vuepic/vue-datepicker/dist/main.css"; +@import "vars.scss"; + +// Must use #{ } +// Remark: https://stackoverflow.com/questions/50202991/unable-to-set-scss-variable-to-css-variable +.dp__theme_dark { + --dp-background-color: #{$dark-bg2}; + --dp-text-color: #{$dark-font-color}; + --dp-hover-color: #484848; + --dp-hover-text-color: #ffffff; + --dp-hover-icon-color: #959595; + --dp-primary-color: #{#5cdd8b}; + --dp-primary-text-color: #ffffff; + --dp-secondary-color: #494949; + --dp-border-color: #{$dark-border-color}; + --dp-menu-border-color: #2d2d2d; + --dp-border-color-hover: #{$dark-border-color}; + --dp-disabled-color: #212121; + --dp-scroll-bar-background: #212121; + --dp-scroll-bar-color: #484848; + --dp-success-color: #{$primary}; + --dp-success-color-disabled: #428f59; + --dp-icon-color: #959595; + --dp-danger-color: #e53935; + --dp-highlight-color: rgba(0, 92, 178, 0.2); +} + +.dp__input { + border-radius: $border-radius; +} + +// Fix: Full width of text input when using "inline textInput inlineWithInput" mode +.dp__main > div[aria-label="Datepicker input"] { + width: 100%; +} + +.dp__main > div[aria-label="Datepicker menu"]:nth-child(2) { + margin-top: 20px; +} diff --git a/src/languages/en.js b/src/languages/en.js index 1a5956f7..d729d3a5 100644 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -18,7 +18,8 @@ export default { "All Status Pages": "All Status Pages", "Selected status pages": "Selected status pages", "Select status pages...": "Select status pages...", - End: "End", + recurringIntervalMessage: "Run once every day | Run once every {0} days", + "End": "End", affectedMonitorsDescription: "Select monitors that are affected by current maintenance", affectedStatusPages: "Show this maintenance message on selected status pages", atLeastOneMonitor: "Select at least one affected monitor", @@ -61,9 +62,7 @@ export default { List: "List", Add: "Add", "Add Monitor": "Add Monitor", - "Add Maintenance": "Add Maintenance", "Add New Monitor": "Add New Monitor", - "Add New Maintenance": "Add New Maintenance", "Quick Stats": "Quick Stats", Up: "Up", Down: "Down", @@ -605,4 +604,21 @@ export default { goAlert: "GoAlert", backupOutdatedWarning: "Deprecated: Since a lot of features added and this backup feature is a bit unmaintained, it cannot generate or restore a complete backup.", backupRecommend: "Please backup the volume or the data folder (./data/) directly instead.", + recurringInterval: "Interval", + "Recurring": "Recurring", + strategyManual: "Active/Inactive Manually", + warningTimezone: "It is NOT your current browser's timezone. It is your server's timezone.", + weekdayShortMon: "Mon", + weekdayShortTue: "Tue", + weekdayShortWed: "Wed", + weekdayShortThu: "Thu", + weekdayShortFri: "Fri", + weekdayShortSat: "Sat", + weekdayShortSun: "Sun", + dayOfMonth: "Day of Month", + lastDay: "Last Day", + lastDay1: "Last Day of Month", + lastDay2: "2nd Last Day of Month", + lastDay3: "3rd Last Day of Month", + lastDay4: "4th Last Day of Month", }; diff --git a/src/main.js b/src/main.js index 18490908..7783882b 100644 --- a/src/main.js +++ b/src/main.js @@ -5,6 +5,7 @@ import Toast from "vue-toastification"; import "vue-toastification/dist/index.css"; import App from "./App.vue"; import "./assets/app.scss"; +import "./assets/vue-datepicker.scss"; import { i18n } from "./i18n"; import { FontAwesomeIcon } from "./icon.js"; import datetime from "./mixins/datetime"; diff --git a/src/mixins/datetime.js b/src/mixins/datetime.js index b8e4db45..0e5317c6 100644 --- a/src/mixins/datetime.js +++ b/src/mixins/datetime.js @@ -26,6 +26,15 @@ export default { return dayjs.tz(value, this.timezone).utc().format(); }, + /** + * Used for + * @param value + * @returns {string} + */ + toDateTimeInputFormat(value) { + return this.datetimeFormat(value, "YYYY-MM-DDTHH:mm"); + }, + /** * Return a given value in the format YYYY-MM-DD HH:mm:ss * @param {any} value Value to format as date time diff --git a/src/mixins/theme.js b/src/mixins/theme.js index 58f4d91b..8d225267 100644 --- a/src/mixins/theme.js +++ b/src/mixins/theme.js @@ -46,6 +46,10 @@ export default { } return this.userTheme; } + }, + + isDark() { + return this.theme === "dark"; } }, diff --git a/src/pages/EditMaintenance.vue b/src/pages/EditMaintenance.vue index f010ca8e..98d5c2b2 100644 --- a/src/pages/EditMaintenance.vue +++ b/src/pages/EditMaintenance.vue @@ -7,7 +7,7 @@
-
+
-

{{ $t("Effective Date Range") }}

+

{{ $t("Date and Time") }}

- -
- - -
+
⚠️ {{ $t("warningTimezone") }}
- +
- - + +
+ + + + + + + + + + + + + + +
+ + {{ $t("deleteMaintenanceMsg") }}