Browse Source

Feature: Mobile - Finalization of the notification handling.

Romit Choudhary 3 years ago
parent
commit
d2c456a438

+ 1 - 0
.eslintrc.js

@@ -63,6 +63,7 @@ module.exports = {
           'vite.config.ts',
           'app/frontend/tests/**/*',
           'app/frontend/stories/**/*',
+          '.storybook/**/*',
         ],
       },
     ],

+ 6 - 3
.storybook/main.ts → .storybook/main.js

@@ -1,5 +1,8 @@
+// Copyright (C) 2012-2021 Zammad Foundation, https://zammad-foundation.org/
+
 const { loadConfigFromFile, mergeConfig } = require('vite')
 const path = require('path')
+const postcss = require('postcss')
 
 module.exports = {
   stories: ['../app/**/*.stories.mdx', '../app/**/*.stories.@(js|jsx|ts|tsx)'],
@@ -16,7 +19,7 @@ module.exports = {
         },
         postcssLoaderOptions: {
           // When using postCSS 8
-          implementation: require('postcss'),
+          implementation: postcss,
         },
       },
     },
@@ -25,7 +28,7 @@ module.exports = {
   core: {
     builder: 'storybook-builder-vite',
   },
-  async viteFinal(storybookViteConfig: any) {
+  async viteFinal(storybookViteConfig) {
     const { config } = await loadConfigFromFile(
       path.resolve(__dirname, '../vite.config.ts'),
     )
@@ -35,7 +38,7 @@ module.exports = {
 
       // Manually specify plugins to avoid conflicts.
       plugins: [
-        config.plugins.find((plugin: any) => plugin.name === 'vite:svg-icons')
+        config.plugins.find((plugin) => plugin.name === 'vite:svg-icons'),
       ],
     })
   },

+ 8 - 4
.storybook/preview.ts

@@ -1,13 +1,17 @@
-import { app } from '@storybook/vue3';
-import { i18n } from '@common/utils/i18n';
+// Copyright (C) 2012-2021 Zammad Foundation, https://zammad-foundation.org/
+
+import { app } from '@storybook/vue3'
+import { i18n } from '@common/utils/i18n'
 import 'virtual:svg-icons-register' // eslint-disable-line import/no-unresolved
 import '@common/styles/main.css'
+import initializeGlobalComponents from '@common/initializer/globalComponents'
 
 // adds translation to app
 app.config.globalProperties.i18n = i18n
+initializeGlobalComponents(app)
 
-export const parameters = {
-  actions: { argTypesRegex: "^on[A-Z].*" },
+export default {
+  actions: { argTypesRegex: '^on[A-Z].*' },
   controls: {
     matchers: {
       color: /(background|color)$/i,

+ 1 - 1
app/assets/javascripts/app/lib/base/word_filter.js

@@ -74,7 +74,7 @@ window.word_filter = function(editor){
         }
     })
 
-    // style and align is handled by utils.coffee itself, don't clean it here
+    // style and align is handled by utils.coffee it self, don't clean it here
     //$('[style]', editor).removeAttr('style');
     //$('[align]', editor).removeAttr('align');
     $('span', editor).replaceWith(function() {return $(this).contents();});

+ 5 - 3
app/frontend/apps/mobile/views/Home.vue

@@ -31,13 +31,14 @@ import { storeToRefs } from 'pinia'
 import { useRouter } from 'vue-router'
 import useApplicationConfigStore from '@common/stores/application/config'
 import { useCurrentUserQuery } from '@common/graphql/api'
+import { NotificationTypes } from '@common/types/notification'
 
 // TODO: Only testing for the notifications...
-const { notify } = useNotifications()
+const { notify, clearAllNotifications } = useNotifications()
 
 notify({
   message: __('Hello Home!!!'),
-  type: 'alert',
+  type: NotificationTypes.WARN,
 })
 
 const sessionUser = useSessionUserStore()
@@ -49,8 +50,9 @@ const authenticated = useAuthenticatedStore()
 const router = useRouter()
 
 const logout = (): void => {
+  clearAllNotifications()
   authenticated.logout().then(() => {
-    router.push('login')
+    router.push('/login')
   })
 }
 

+ 2 - 1
app/frontend/apps/mobile/views/Login.vue

@@ -89,6 +89,7 @@ import useNotifications from '@common/composables/useNotifications'
 import useApplicationConfigStore from '@common/stores/application/config'
 import useAuthenticationStore from '@common/stores/authenticated'
 import { useRouter } from 'vue-router'
+import { NotificationTypes } from '@common/types/notification'
 
 interface Props {
   invalidatedSession?: string
@@ -103,7 +104,7 @@ if (props.invalidatedSession === '1') {
 
   notify({
     message: __('The session is no longer valid. Please log in again.'),
-    type: 'warning',
+    type: NotificationTypes.WARN,
   })
 }
 

+ 33 - 4
app/frontend/common/components/common/CommonNotifications.vue

@@ -10,12 +10,22 @@
       >
         <div v-for="notification in notifications" v-bind:key="notification.id">
           <div class="flex justify-center">
-            <div class="flex items-center bg-black p-2 rounded text-white m-1">
+            <div
+              class="flex items-center py-2 px-4 rounded m-1"
+              v-bind:class="getClassName(notification.type)"
+            >
               <CommonIcon
-                name="diagonal-cross"
-                v-bind:fixed-size="{ width: 16, height: 16 }"
+                v-bind:name="iconNameMap[notification.type]"
+                v-bind:fixed-size="{ width: 10, height: 10 }"
               />
-              <span class="ml-2">{{ notification.message }}</span>
+              <span class="ml-2 text-sm">{{
+                notification.messagePlaceholder
+                  ? i18n.t(
+                      notification.message,
+                      ...notification.messagePlaceholder,
+                    )
+                  : i18n.t(notification.message)
+              }}</span>
             </div>
           </div>
         </div>
@@ -26,6 +36,25 @@
 
 <script setup lang="ts">
 import useNotifications from '@common/composables/useNotifications'
+import { NotificationTypes } from '@common/types/notification'
+
+const notificationTypeClassMap = {
+  warn: 'bg-yellow-500 text-white',
+  success: 'bg-green-500 text-white',
+  error: 'bg-red-500 text-white',
+  info: 'bg-white text-black',
+}
+
+const iconNameMap = {
+  warn: 'info',
+  success: 'checkmark',
+  error: 'danger',
+  info: 'info',
+}
 
 const { notifications } = useNotifications()
+
+const getClassName = (notificationType: NotificationTypes) => {
+  return notificationTypeClassMap[notificationType]
+}
 </script>

+ 9 - 12
app/frontend/common/composables/useNotifications.ts

@@ -2,18 +2,10 @@
 
 import { v4 as uuid } from 'uuid'
 import { ref } from 'vue'
-
-interface NewNotificationInterface {
-  id?: string
-  message: string
-  messagePlaceholder?: string[]
-  type: string // TODO type for different types or enum?
-  duration?: number
-}
-
-interface NotificationInterface extends NewNotificationInterface {
-  id: string
-}
+import type {
+  NewNotificationInterface,
+  NotificationInterface,
+} from '@common/types/notification'
 
 const notifications = ref<NotificationInterface[]>([])
 const defaultNotificationDuration = 5000
@@ -24,6 +16,10 @@ function removeNotification(id: string) {
   )
 }
 
+function clearAllNotifications() {
+  notifications.value = []
+}
+
 export default function useNotifications() {
   function notify(notification: NewNotificationInterface): string {
     // TODO: Check different solution for the optional id in the interface, but required field in the removeNotification function.
@@ -46,5 +42,6 @@ export default function useNotifications() {
   return {
     notify,
     notifications,
+    clearAllNotifications,
   }
 }

+ 2 - 1
app/frontend/common/server/apollo/handler/BaseHandler.ts

@@ -10,6 +10,7 @@ import {
 } from '@common/types/server/apollo/handler'
 import { Ref } from 'vue'
 import useNotifications from '@common/composables/useNotifications'
+import { NotificationTypes } from '@common/types/notification'
 import {
   GraphQLErrorReport,
   GraphQLErrorTypes,
@@ -31,7 +32,7 @@ export default abstract class BaseHandler<
     errorShowNotification: true,
     errorNotitifactionMessage:
       'An error occured during the operation. Please contact your administrator.',
-    errorNotitifactionType: 'error',
+    errorNotitifactionType: NotificationTypes.ERROR,
   }
 
   public handlerOptions!: CommonHandlerOptions<THandlerOptions>

+ 20 - 0
app/frontend/common/types/notification.ts

@@ -0,0 +1,20 @@
+// Copyright (C) 2012-2021 Zammad Foundation, https://zammad-foundation.org/
+
+export enum NotificationTypes {
+  WARN = 'warn',
+  SUCCESS = 'success',
+  ERROR = 'error',
+  INFO = 'info',
+}
+
+export interface NewNotificationInterface {
+  id?: string
+  message: string
+  messagePlaceholder?: string[]
+  type: NotificationTypes
+  duration?: number
+}
+
+export interface NotificationInterface extends NewNotificationInterface {
+  id: string
+}

Some files were not shown because too many files changed in this diff