tolgee-platform icon indicating copy to clipboard operation
tolgee-platform copied to clipboard

Activity and notifications

Open ZuzanaOdstrcilova opened this issue 2 years ago • 4 comments

Activity view on dashboard Image

  • [ ] redesign activity view (infinite scroll, activity stream button)
  • [ ] implement logic - grouping activities (time, user, activity)
  • [ ] implement / discuss basic filters on dashboard (user, activity...)
  • [ ] hover, on click activity group in dialog Image
  • [ ] button activity stream will open page with all activities (needs discussion if it will be in menu)

Activity stream Image

  • [ ] new full screen view of activities (same content like in activity on dash, but bigger, better filters)
  • [ ] filters, (infinite scroll or pagination - to be discussed) Image
  • [ ] there are examples of groups and tables for different content Image

Notifications Image

  • [ ] design of notifiations
  • [ ] logic (notifications are grouped, hide number after opening menu, stream of last notifications, just main events and settings)
  • [ ] settings - to be discussed

Emails

  • [ ] sumarization of activities in spec time - discussion
  • [ ] specific notifications like comments could be send as one notification
  • [ ] settings
  • [ ] UI to disuss, links to platform

Mentions in comments

  • [ ] When user is mentioned in translation comment, we should notify them.

More in detail in Figma: https://www.figma.com/design/wVmz098ZrSxswOI0nbIjQ2/Design-system-Tolgee?node-id=1111-22910&t=DjPqF3TlX7U7SGkN-1

ZuzanaOdstrcilova avatar Apr 15 '24 10:04 ZuzanaOdstrcilova

Unification of these issues:

  • https://github.com/tolgee/tolgee-platform/issues/2128
  • https://github.com/tolgee/tolgee-platform/issues/2198
  • https://github.com/tolgee/tolgee-platform/issues/2053
  • https://github.com/tolgee/tolgee-platform/issues/2054
  • https://github.com/tolgee/tolgee-platform/issues/1984
  • https://github.com/tolgee/tolgee-platform/issues/1975 (not in the first design)
  • https://github.com/tolgee/tolgee-platform/issues/1800 (activity)
  • https://github.com/tolgee/tolgee-platform/issues/1723 (key history)

Notes from old issues - designed in Figma:

  • [x] The rows have hover state, while there are not clickable
  • [x] There is 3 dots on the right, while is suggest it will open dropdown, while it opens detail dialog instead. This should be removed and the row should be clickable
  • [x] For larger operation (like modification of multiple fields on key) it shows ... under each section. Please get rid of it.
  • [x] When user imports data they cannot see what data is imported
  • [x] There is load more button, it should be probably changed to infinite scroll
  • [x] There should exist a special view with filtering by user
  • [x] For operations without special detail, the clicking should be disabled
  • [x] fix issue with activity while adding screenshots
  • [x] Add a filter by language in the Members section
  • [x] Add a filter by language in the Activity section of the dashboard
  • [x] problem: load more (activity), ideas: Being able to open in full width the Activity part of the dashboard, Having a pagination that ease the navigation throughout the activities
  • [x] E-mail notification from comments
  • [x] Filtering of activities
  • [ ] Discord
  • [ ] History - key
  • [x] Pluralization in activity

ZuzanaOdstrcilova avatar Apr 15 '24 10:04 ZuzanaOdstrcilova

We should also solve changes in plurals ans switching from/to plurals - how to visualize them in history and activity. https://github.com/tolgee/tolgee-platform/issues/2172

stepan662 avatar Apr 16 '24 08:04 stepan662

user feedback about imports activity: the absence of a history of imports feature makes it challenging to track past actions. Well the thing that I mean was simply a history of imports in import section (with some details like the file name, date, user, number of keys if possible)

marketachalupnikova avatar Apr 17 '24 07:04 marketachalupnikova

I've created this activity groups list, so we can group the activities in the list:

enum class ActivityGroup(
  val sourceActivityTypes: List<ActivityType>,
  val allowedEntityModifications: List<EntityModification<*>>,
) {
  SET_TRANSLATION_STATE(
    listOf(ActivityType.SET_TRANSLATION_STATE, ActivityType.COMPLEX_EDIT),
    listOf(
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(Translation::state, Translation::outdated, Translation::mtProvider),
      ),
    ),
  ),

  SET_TRANSLATIONS(
    listOf(ActivityType.SET_TRANSLATIONS, ActivityType.COMPLEX_EDIT),
    listOf(
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.ADD, RevisionType.DEL, RevisionType.MOD),
      ),
    ),
  ),

  DISMISS_AUTO_TRANSLATED_STATE(
    listOf(ActivityType.DISMISS_AUTO_TRANSLATED_STATE),
    listOf(
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(Translation::auto, Translation::mtProvider),
        allowedValues = mapOf(Translation::mtProvider to null, Translation::auto to false),
      ),
    ),
  ),

  SET_OUTDATED_FLAG(
    listOf(ActivityType.SET_OUTDATED_FLAG),
    listOf(
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(Translation::outdated),
      ),
    ),
  ),

  TRANSLATION_COMMENT_ADD(
    listOf(ActivityType.TRANSLATION_COMMENT_ADD),
    listOf(
      EntityModification(
        entityClass = TranslationComment::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.ADD),
      )
    ),
  ),

  TRANSLATION_COMMENT_DELETE(
    listOf(ActivityType.TRANSLATION_COMMENT_DELETE),
    listOf(
      EntityModification(
        entityClass = TranslationComment::class,
        revisionTypes = listOf(RevisionType.DEL),
      ),
    ),
  ),

  TRANSLATION_COMMENT_EDIT(
    listOf(ActivityType.TRANSLATION_COMMENT_EDIT),
    listOf(
      EntityModification(
        entityClass = TranslationComment::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(TranslationComment::text),
      ),
    ),
  ),

  TRANSLATION_COMMENT_SET_STATE(
    listOf(ActivityType.TRANSLATION_COMMENT_SET_STATE),
    listOf(
      EntityModification(
        entityClass = TranslationComment::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(TranslationComment::state),
      ),
    ),
  ),

  SCREENSHOT_DELETE(
    listOf(ActivityType.SCREENSHOT_DELETE, ActivityType.COMPLEX_EDIT),
    listOf(
      EntityModification(
        entityClass = Screenshot::class,
        revisionTypes = listOf(RevisionType.DEL),
      ),
      EntityModification(
        entityClass = KeyScreenshotReference::class,
        revisionTypes = listOf(RevisionType.DEL),
      ),
    ),
  ),

  SCREENSHOT_ADD(
    listOf(ActivityType.SCREENSHOT_ADD, ActivityType.COMPLEX_EDIT),
    listOf(
      EntityModification(
        entityClass = Screenshot::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
      EntityModification(
        entityClass = KeyScreenshotReference::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
    ),
  ),

  KEY_TAGS_EDIT(
    listOf(
      ActivityType.KEY_TAGS_EDIT, ActivityType.COMPLEX_EDIT, ActivityType.BATCH_TAG_KEYS,
      ActivityType.BATCH_UNTAG_KEYS
    ),
    listOf(
      EntityModification(
        entityClass = KeyMeta::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(KeyMeta::tags),
      ),
      EntityModification(
        entityClass = Tag::class,
        revisionTypes = listOf(RevisionType.ADD, RevisionType.DEL),
      ),
    ),
  ),

  KEY_NAME_EDIT(
    listOf(ActivityType.KEY_NAME_EDIT, ActivityType.COMPLEX_EDIT),
    listOf(
      EntityModification(
        entityClass = Key::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(Key::name, Key::namespace),
      ),
      EntityModification(
        entityClass = Namespace::class,
        revisionTypes = listOf(RevisionType.ADD, RevisionType.DEL),
      ),
    )
  ),

  KEY_DELETE(
    listOf(ActivityType.KEY_DELETE),
    listOf(
      EntityModification(
        entityClass = Key::class,
        revisionTypes = listOf(RevisionType.DEL),
      ),
    ),
  ),

  KEY_CREATE(
    listOf(ActivityType.CREATE_KEY),
    listOf(
      EntityModification(
        entityClass = Key::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
      EntityModification(
        entityClass = KeyMeta::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
    ),
  ),

  IMPORT(
    listOf(ActivityType.IMPORT),
    listOf(
      EntityModification(
        entityClass = Key::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
      EntityModification(
        entityClass = KeyMeta::class,
        revisionTypes = listOf(RevisionType.ADD, RevisionType.MOD),
        modificationProps = listOf(KeyMeta::custom, KeyMeta::description),
      ),
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
      EntityModification(
        entityClass = Namespace::class,
        revisionTypes = listOf(RevisionType.ADD, RevisionType.DEL),
      ),
    )
  ),

  CREATE_LANGUAGE(
    listOf(ActivityType.CREATE_LANGUAGE),
    listOf(
      EntityModification(
        entityClass = Language::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
    )
  ),

  EDIT_LANGUAGE(
    listOf(ActivityType.EDIT_LANGUAGE),
    listOf(
      EntityModification(
        entityClass = Language::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(Language::name, Language::tag, Language::originalName, Language::flagEmoji),
      ),
    )
  ),

  DELETE_LANGUAGE(
    listOf(ActivityType.DELETE_LANGUAGE),
    listOf(
      EntityModification(
        entityClass = Language::class,
        revisionTypes = listOf(RevisionType.DEL),
      ),
    )
  ),

  CREATE_PROJECT(
    listOf(ActivityType.CREATE_PROJECT),
    listOf(
      EntityModification(
        entityClass = Project::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
    )
  ),

  EDIT_PROJECT(
    listOf(ActivityType.EDIT_PROJECT),
    listOf(
      EntityModification(
        entityClass = Project::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(
          Project::name,
          Project::description,
          Project::baseLanguage,
          Project::defaultNamespace,
          Project::avatarHash
        ),
      ),
    )
  ),

  NAMESPACE_EDIT(
    listOf(ActivityType.NAMESPACE_EDIT, ActivityType.BATCH_SET_KEYS_NAMESPACE),
    listOf(
      EntityModification(
        entityClass = Namespace::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(Namespace::name),
      ),
    )
  ),

  BATCH_PRE_TRANSLATE_BY_TM(
    listOf(ActivityType.BATCH_PRE_TRANSLATE_BY_TM),
    listOf(
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.MOD, RevisionType.ADD),
        modificationProps = listOf(Translation::state, Translation::text, Translation::outdated, Translation::auto),
      ),
    )
  ),

  BATCH_MACHINE_TRANSLATE(
    listOf(ActivityType.BATCH_MACHINE_TRANSLATE),
    listOf(
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.MOD, RevisionType.ADD),
        modificationProps = listOf(Translation::state, Translation::text, Translation::outdated, Translation::auto),
      ),
    )
  ),

  AUTO_TRANSLATE(
    listOf(ActivityType.AUTO_TRANSLATE),
    listOf(
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.MOD, RevisionType.ADD),
        modificationProps = listOf(Translation::state, Translation::text, Translation::outdated, Translation::auto),
      ),
    )
  ),

  BATCH_CLEAR_TRANSLATIONS(
    listOf(ActivityType.BATCH_CLEAR_TRANSLATIONS),
    listOf(
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(Translation::state, Translation::text, Translation::outdated, Translation::auto),
        allowedValues = mapOf(
          Translation::text to null,
          Translation::state to null,
          Translation::outdated to false,
          Translation::auto to false
        ),
      ),
    )
  ),

  BATCH_COPY_TRANSLATIONS(
    listOf(ActivityType.BATCH_COPY_TRANSLATIONS),
    listOf(
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.MOD, RevisionType.ADD),
        modificationProps = listOf(Translation::state, Translation::text, Translation::outdated, Translation::auto),
      ),
    )
  ),

  BATCH_SET_TRANSLATION_STATE(
    listOf(ActivityType.BATCH_SET_TRANSLATION_STATE),
    listOf(
      EntityModification(
        entityClass = Translation::class,
        revisionTypes = listOf(RevisionType.MOD),
        modificationProps = listOf(Translation::state, Translation::outdated, Translation::auto),
      ),
    )
  ),

  CONTENT_DELIVERY_CONFIG_CREATE(
    listOf(ActivityType.CONTENT_DELIVERY_CONFIG_CREATE),
    listOf(
      EntityModification(
        entityClass = ContentDeliveryConfig::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
    )
  ),

  CONTENT_DELIVERY_CONFIG_UPDATE(
    listOf(ActivityType.CONTENT_DELIVERY_CONFIG_UPDATE),
    listOf(
      EntityModification(
        entityClass = ContentDeliveryConfig::class,
        revisionTypes = listOf(RevisionType.MOD),
      ),
    )
  ),


  CONTENT_DELIVERY_CONFIG_DELETE(
    listOf(ActivityType.CONTENT_DELIVERY_CONFIG_UPDATE),
    listOf(
      EntityModification(
        entityClass = ContentDeliveryConfig::class,
        revisionTypes = listOf(RevisionType.DEL),
      ),
    )
  ),

  CONTENT_STORAGE_CREATE(
    listOf(ActivityType.CONTENT_STORAGE_CREATE),
    listOf(
      EntityModification(
        entityClass = ContentStorage::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
    )
  ),

  CONTENT_STORAGE_UPDATE(
    listOf(ActivityType.CONTENT_STORAGE_UPDATE),
    listOf(
      EntityModification(
        entityClass = ContentStorage::class,
        revisionTypes = listOf(RevisionType.MOD),
      ),
    )
  ),

  CONTENT_STORAGE_DELETE(
    listOf(ActivityType.CONTENT_STORAGE_DELETE),
    listOf(
      EntityModification(
        entityClass = ContentStorage::class,
        revisionTypes = listOf(RevisionType.DEL),
      ),
    )
  ),

  WEBHOOK_CONFIG_CREATE(
    listOf(ActivityType.WEBHOOK_CONFIG_CREATE),
    listOf(
      EntityModification(
        entityClass = WebhookConfig::class,
        revisionTypes = listOf(RevisionType.ADD),
      ),
    )
  ),

  WEBHOOK_CONFIG_UPDATE(
    listOf(ActivityType.WEBHOOK_CONFIG_CREATE),
    listOf(
      EntityModification(
        entityClass = WebhookConfig::class,
        revisionTypes = listOf(RevisionType.MOD),
      ),
    )
  ),

  WEBHOOK_CONFIG_DELETE(
    listOf(ActivityType.WEBHOOK_CONFIG_CREATE),
    listOf(
      EntityModification(
        entityClass = WebhookConfig::class,
        revisionTypes = listOf(RevisionType.DEL),
      ),
    )
  ),
}

JanCizmar avatar May 21 '24 10:05 JanCizmar