diff --git a/Documentation-develop/CHAT.md b/Documentation-develop/CHAT.md index 05cc3dbcc9201f4d7b2d1604d4c5949959d34e20..5be916eced407e4466b7a3a346588aef607e32ca 100644 --- a/Documentation-develop/CHAT.md +++ b/Documentation-develop/CHAT.md @@ -21,26 +21,23 @@ ### V1.0 * Chat-Rooms -* User kann eingeloggt sein oder nicht (Anonymous) - +* Anonymous: User kann eingeloggt sein oder nicht. * Hintergrund 'Anonym': wenig Mehraufwand, es kann direkt auf einem Tool ein Chatfenster angezeigt werden um Kontakt aufzunehmen. * Ziel: Support Channel (I-MATH) in RC aufloesen und ein Chat Fenster auf MY anbieten. Gleiches fuer diverse andere QFQ Tools. - * Anzeige Nachrichten: - - * By default nur die 10 neuesten Nachrichten. - * Suche in Nachrichten moeglich. + * By default nur die 10 neuesten Nachrichten. + * Suche in Nachrichten moeglich. ### V1.1 -* Thread pro Chat-Room. +* Thread Support. * Anzeige Nachrichten: Lazy Loading. ### V1.2 -* Flag 'Done' pro Chat-Room / Thread. +* Tag _'Done'_ pro Chat-Room / Thread. * Dashboard Ideen (ist vermutlich keine PHP Implementierung sondern nur Best Practice SQL Queries): * Anzahl offener Anfragen. * Anzahl offener Anfragen aelter als 8 Arbeitsstunden (critical). @@ -77,32 +74,34 @@ * Split Thread: Teilnehmer (Admin oder Creator) kann einen bestehenden Thread teilen. Bsp: Die Diskussion beginnt ein weiteres Topic (oder User stellt mehrere Fragen) die einzeln behandelt werden sollen. -* Option: optionDoneResetOnNewMessage +* Option: optionTagDoneResetOnNewMessage * Tags pro Messages vergeben. ## Konzept ### Table 'Chat' -| Column | Type | Comment | -|-------------|------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| -| id | \<int> | - | -| cIdTopic | \<int> | - | -| xId | \<int> | Antrag.id, Person.id, ... | -| cIdThread | \<int> | =0 bei Thread Start. Pointer auf die erste Messages eines Thread | -| message | \<text> | Chat Nachricht | -| type | enum('message', 'topic', 'done', 'read', 'reminder') | type='Message,done,reminder' wird von Chat Teilnehmern angelegt. type='Topic' wird i.d.R. von QFQ Dev angelegt | -| reference | <varchar> | Aktuell nur bei type='Topic'. Wird i.d.R. von QFQ Dev gesetzt | -| cIdLastRead | \<int> | Bei type=read: Pointer auf die zuletzt gelesene Message des pIdCreator. | -| username | \<varchar> | Angezeigter Name im Chat Fenster | -| pIdCreator | \<int> | Eindeutige Zuordnung zu einer Person | +| Column | Type | Comment | +|-------------|-----------------------------------------------------|---------------------------------------------------------------------------------------------------------------| +| id | \<int> | - | +| cIdTopic | \<int> | - | +| xId | \<int> | Antrag.id, Person.id, ... | +| cIdThread | \<int> | =0 bei Thread Start. Pointer auf die erste Messages eines Thread | +| message | \<text> | Chat Nachricht | +| type | enum('message', 'topic', 'tag', 'read', 'reminder') | type='Message,tag,reminder' wird von Chat Teilnehmern angelegt. type='Topic' wird i.d.R. von QFQ Dev angelegt | +| reference | <varchar> | Aktuell nur bei type='Topic'. Wird i.d.R. von QFQ Dev gesetzt | +| cIdLastRead | \<int> | Bei type=read: Pointer auf die zuletzt gelesene Message des pIdCreator. | +| username | \<varchar> | Angezeigter Name im Chat Fenster | +| pIdCreator | \<int> | Eindeutige Zuordnung zu einer Person | +| emoticon | \<varchar> | 'thumbsup:enured,crose;smiley:crose,jhaller,bbaer | * Records mit einer 'reference' werden gesynct. * Im aktuellen Konzept haben nur Chat.type='Topic' Records eine Reference. * Damit werden Chat-Rooms implizit Applikationslogik, denn diese werden bei einem Sync angelegt (falls die noch nicht existieren). - * Werden neue Chat-Rooms auf 'prod' angelegt, bleiben sie bei einem Sync unberuehrt (ok). + * Werden neue Chat-Rooms auf 'prod' angelegt, bleiben sie bei einem Sync unberuehrt (ok). D.h. es + Applikations-Chat-Rooms und Custom-Chat-Rooms. ### FormElement.parameter @@ -114,28 +113,29 @@ thread=0|1 cIdTopic= xId= -# Person die die Message erstellt hat. Sonderfall: Bei Teams wird hier eine Fake Person eingetragen (z.B. Person.name='Team A') +# Person die die Message erstellt hat. pIdCreator={{pIdFeUser}} # Mapping das FE.Chat auch mit anderen Tabellen, Spaltennamen arbeiten kann. columnMap=[apId:xId,pId:pIdCreator,grIdStatus:xGrIdStatus,...] tableName=history[, note] -# Displayname des aktuellen Users. Bei Teams koennte das z.B. die reale Person sein, pIdCreator zeigt aber auf das Team. +# Displayname des aktuellen Users. Bei Teams koennte das z.B. die reale Person sein, pIdCreator zeigt auf das Team. username = {{SELECT p.firstname, ' ', p.lastname FROM Person WHERE p.account='{{feUser:UT}}' }} # TBD: wo genau brauchen wir den noch? xGrIdStatus (optional) -# Optional kann ein Teilnehmer pro Chat / Thread ein Flag 'done' setzen. -# `off` - Es kann kein Flag 'done' gesetzt werden. -# `all` - Jeder Teilnehmer kann ein Flag 'done' setzen/loeschen. Im Chat wird angezeigt welche Personen ein Flag 'done' gesetzt haben. -# 'my' - Jeder Teilnehmer kann ein Flag 'done' setzen/loeschen. Im Chat wird nur angezeigt wenn man selbst ein Flag 'done' gesetzt hat. -optionDone=*off|all|my +# Optional kann ein Teilnehmer pro Chat / Thread Tag(s) setzen. +# `off` - Es kann kein Tag gesetzt werden. +# `all` - Jeder Teilnehmer kann Tag(s) setzen/loeschen. Im Chat wird angezeigt welche Personen welches Tag gesetzt haben. +# 'my' - Jeder Teilnehmer kann Tag(s) setzen/loeschen. Im Chat wird nur die eigenen Tags angezeigt. +optionTag=*off|all|my +optionTagDone=*off|all|my -# 0: Done Flag wird vollstaendig manuell kontrolliert. -# 1: Ist das done Flag gesetzt und wird eine neue Message gesendet, wird das done Flag automatisch geloescht. -optionDoneResetOnNewMessage=0|1 +# 0: Tag Done wird vollstaendig manuell kontrolliert. +# 1: Ist der Tag _'Done'_ gesetzt und wird eine neue Message gesendet, wird der Tag _'Done'_ automatisch geloescht. +optionTagDoneResetOnNewMessage=0|1 # Pro Teilnehmer kann auf einem Chat / Thread ein Reminder gesetzt werden. optionReminder=0|1 @@ -150,7 +150,7 @@ username={{username:V}} pIdCreator={{pId:V}} xId={{id:R}} thread=0|1 -optionDone=all +optionTagDone=all </pre> ### Chat-Room @@ -158,32 +158,39 @@ optionDone=all Es gibt zwei Sorten von Chat-Rooms: * General Topic : z.B. Support Anfrage. -* Topic per Request : Pro User (oder pro Antrag) und Topic (Rueckfrage an Antragsteller, Rueckfrage bei Stv.Dean, ...) +* Topic per Request : Pro Topic (Rueckfrage an Antragsteller, Rueckfrage bei Stv.Dean, ...) und pro User (oder pro + Antrag). -Bei einen `General Topic` kann `per Request` einfach leer gelassen werden (=0). +Bei einen `General Topic` kann `per Request` einfach leer gelassen werden (xId=0). Die Chat-Rooms (name, id) werden in der Tabelle `Chat` gespeichert mit `Chat.type='topic'`. +* Tabelle Chat: + * type='topic' + * cIdTopic, xId: keine Bedeutung + * reference: <topic name> + * message=<...> - Optional, beschreibt den Chat-Room. + ### Thread Motivation: In einem Chat-Room, in dem viele Personen Anfragen stellen koennen, geht schnell die Übersicht verloren wer mit wem was diskutiert. _Threads_ innerhalb eines Chats helfen die Uebersicht zu behalten. -Pro FE.type='Chat' kann konfiguriert werden ob @FE.parameter.threads=0|1@ moeglich sind. +* FE.parameter: + * threads=0|1 - Threads sind erlaubt ja/nein. Umsetzung: * Column: Chat.cIdThread -* Bei dem ersten Message-Record eines Threads ist `Chat.cIdThreadId=0` - das ist implizit das Flag das bei diesem Record - ein - Thread startet. -* Alle weiteren Message-Records des Threads zeigen mit `Chat.cIdThreadId=...` auf den ersten Thread Message-Record. +* Bei dem ersten Message-Record eines Threads ist `Chat.cIdThreadId=0` - das ist implizit das Flag das bei diesem + Record ein Thread startet. +* Alle weiteren Message-Records des Threads zeigen (id) mit `Chat.cIdThreadId=...` auf den ersten Thread Message-Record. UI: * By default ist der neueste Thread ausgeklappt und _aktiv_, alle anderen Threads sind zusammen geklappt (vergleichbar RC). -* Durch anklicken eines anderen Thread wird dieser aktiv und aufgeklappt. Die anderen Threads sind inaktiv/gemuted. +* Durch anklicken eines Threads wird dieser aktiv und auf-/zugeklappt. Die anderen Threads sind inaktiv/gemuted. * Die Message Eingabe Textbox (sticky, unten) sendet immer in den zuletzt aktivierten Thread (in RC ist das anders geloest). * New Message: @@ -193,6 +200,7 @@ UI: <pre> +Dekanat: cxxxxdgsdg +Dekanat: cxxxxdgsdg + +skdafhsdkafhsdakf: Antragsteller +Dekanat: cxxxxdgsdg Dekanat: cxxxxdgsdg skdafhsdkafhsdakf: Antragsteller @@ -206,42 +214,66 @@ Dekanat: cxxxxdgsdg ------------------------------------------ </pre> -### Flag 'done' +### Tag -* Optional kann ein Flag 'Done' gesetzt werden pro Chat Teilnehmer und Chat/Thread. -* Ziel: - * Die Übersicht behalten in Chat-Rooms mit vielen Anfragen welche Punkte noch zu tun sind. - * Auf einem Dashboard anzeigen, in welchen Chat-Rooms noch etwas zu tun ist (typischerweise gab es bei einem Antrag - eine Rückfrage). +* Motivation: + * User koennen so die Chats/Threads mit eigenen Tags markieren. + * Optional werden Tags vorgegeben die z.B. auch auf Antraegen liegen koennen. + * Auf einem Dashboard anzeigen, in welchen Chat-Room welche Tags zugeordnet sind. +* Optional koennen Tags gesetzt werden pro Chat Teilnehmer und Chat/Thread (nicht pro Message). * Darstellung: - * FE.thread=0: Oben rechts 'done: John, Jane' - * FE.thread=1: Im Thread Rahmen oben rechts 'done: John, Jane' -* Ein `Chat.type=done` Record symbolisiert 'done' fuer den Chat/Thread und den User `Chat.pIdCreator`. -* Soll das Flag 'done' wieder geloescht werden, wird der Record geloescht. - * Hintergrund: nur wenige User werden den done-Mechanismus nutzen, damit werden dann nur die wirklich noetigen + * FE.thread=0: Oben rechts '<tag>: John, Jane' + * FE.thread=1: Im Thread Rahmen oben rechts '<tag>: John, Jane' +* Soll ein Tag wieder geloescht werden, wird der Record geloescht. + * Hintergrund: nur wenige User werden den Tag-Mechanismus nutzen, damit werden dann nur die wirklich noetigen Records angelegt. * Mit dem loeschen muss nicht zusaetzlich ein value on/off gemanaged werden. -* Pro Chat/Thread koennen beliebig viele `Chat.type=done` Records angelegt werden. D.h. jeder User kann fuer sich - markieren ob dieser Chat/Thread fuer ihn 'done' ist. -* Change: User klickt auf das 'done' Icon. +* Pro Chat/Thread koennen beliebig viele `Chat.type=tag` Records angelegt werden. D.h. jeder User kann fuer sich + Tags vergeben. +* Change: User klickt auf das Tag Icon. + * Es oeffnet sich ein Typeahead Input Feld in dem die bestehende Tags ausgewaehlt oder neue erfasst werden. * API Aufruf save.php - * Der Done Status wird gesetzt oder geloescht, je nachdem was vorher war. - * Es wird ein 'Refresh' an den Websocket gesendet, um alle registrierten Clients zu informier die Messages, inkl. - Done Status, neu zu laden. + * Das Tag wird gesetzt oder geloescht, je nachdem was vorher war. + * Es wird ein 'Refresh' an den Websocket gesendet, um alle registrierten Clients zu informieren die Messages, inkl. + Tags, neu zu laden. -* Mode 'Set Status Done' +* Beschreibung 'Update Tag' * FE.type=Chat wird geladen * Value: 0|1 - * Check ob es bereits ein Record 'done' zu dem aktuellen Chat/Thread gibt. + * Data: Tag Name + * Check ob es bereits einen Tag Record von dem User in dem Chat / Thread mit dem Tag gibt. * Nein & value==1: es wird ein Record angelegt. * Ja & value==0: der Record wird geloescht. +* Parameter + * optionTag=*off|all|my + * Tabelle Chat: - * type='done' + * type='tag' * cIdTopic, xId: pro Chat-Room * cIdThread: pro Thread moeglich - * pIdCreator: Person fuer die dieser Chat/Thread als 'done' markiert ist. + * pIdCreator: Person die den Tag gesetzt hat. + * message=<Tag Name> + +### Tag _'Done'_ + +* Motivation: + * Die Übersicht behalten in Chat-Rooms mit vielen Anfragen welche Anfragen noch offen sind. + * Auf einem Dashboard anzeigen, in welchen Chat-Rooms offene Anfragen sind (typischerweise gab es bei einem Antrag + eine Rückfrage). + +* Ientisch mit 'Tag' - hat aber eine besondere Bedeutung. +* Der Tag Name ist '\__done' (Tags deren Name mit '__' beginnt sind System Tags) +* Im Chat gibt es ein eigenes Icon um 'done' zu setzen/loeschen. Es muss kein 'Tag Name' angegeben werden. +* Darstellung: + * FE.thread=0: Oben rechts 'done: John, Jane' + * FE.thread=1: Im Thread Rahmen oben rechts 'done: John, Jane' +* Ein `Chat.type='tag', Chat.message='__done'` Record symbolisiert _'Done'_ fuer den Chat/Thread und den User + `Chat.pIdCreator`. +* Parameter: + * optionTagDone=*off|all|my + * optionTagDoneResetOnNewMessage ### Status 'read' @@ -249,13 +281,11 @@ Dekanat: cxxxxdgsdg * Alle Chat.id die groesser sind als dieser Wert, werden als 'ungelesen' dargestellt: Strich 'unread' hinter der letzten gelesenen Nachricht. * Update Chat.cIdLastRead: - * Sobald man selbst eine Nachrict sendet. - * Wenn man den Chat einmal aufgerufen hat und die Message angezeigt (geladen) wurde: beim naechsten oeffnen des - Chats - ist die Nachricht 'gelesen'. -* Speicherort: aktuelles Konzept ist das der Chat Record mit Chat.mode='read' pro User und Chat-Room angelegt wird ( - sobald - der User das erste mal den Chat aufmacht. + * Sobald man selbst eine Nachrict sendet. + * Wenn man den Chat einmal aufgerufen hat und die Message angezeigt (geladen) wurde: beim naechsten oeffnen des + Chats ist die Nachricht 'gelesen'. +* Speicherort: aktuelles Konzept ist das der Chat Record mit Chat.mode='read' pro User und Chat-Room angelegt wird + (sobald der User das erste mal den Chat aufmacht). * Tabelle Chat: * type='read' * cIdTopic, xId: pro Chat-Room @@ -265,20 +295,18 @@ Dekanat: cxxxxdgsdg ### Reminder * Synonym: Reminder=Wiedervorlage=Deadline -* Pro 'Chat / Thread / User|Team' waere es gut wenn Reminder gesetzt werden koennte. Ob das noch feiner sein soll (pro - Message) - ist nicht klar. +* Motivation: + * Pro 'Chat / Thread / User|Team' waere es gut wenn Reminder gesetzt werden koennte. Ob das noch feiner sein soll (pro + Message) ist nicht klar. * Da Reminder ein allgemeines Thema sind, sollte das ggfs. eine Tabelle sein die nicht nur auf den Chat hindeutet (Wahl des Namens). * Es waere auch gut wenn das fuer Gruppen moeglich waere. Bsp: Im IT Support ist ein User Request, ein Mitarbeiter - stellt - eine Rueckfrage an den User (mit Deadline=24h) und ist am naechsten Tag aber nicht da, der User antwortet nicht bis - zur Deadline und der IT Support vom Folgetag sollte aktiv werden (=Reminder poppt beim Support auf). -* Die Reminder - - * Werden auf dem Dashboard angezeigt. - * Koennen eine Email ausloesen. - * Koennen gemuted werden (.z.B. 24h) + stellt eine Rueckfrage an den User (mit Deadline=24h) und ist am naechsten Tag aber nicht da, der User antwortet + nicht bis zur Deadline und der IT Support vom Folgetag sollte aktiv werden (=Reminder poppt beim Support auf). +* Die Reminder: + * Werden auf dem Dashboard angezeigt. + * Koennen eine Email ausloesen. + * Koennen gemuted werden (.z.B. 24h) * Tabelle Chat: * type='reminder' @@ -292,10 +320,15 @@ Dekanat: cxxxxdgsdg TBD -### Emoticons +### Emoticon -* Pro Message -* Chat.emoticons = 'thumbsup:enured,crose;smiley:crose,jhaller,bbaer' +Pro Message gibt es einen String `emoticon`. Das ist leicht zu implementieren und erzeugt keinen zusaetzlichen SQL +Aufwand. + +* Tabelle Chat: + * type='message' + * emoticon = 'thumbsup:john,jane;smiley:jimmy' - Es wird der 'username' abgelegt. + * Alle weiteren Spalten wie bei einer Message. ### Team @@ -314,7 +347,7 @@ Frage: brauchen wir wirklich diese Art von Teams? * Koennte das gleiche nicht implizit erreicht werden? Ein 'Team' kennt alle 'seine' Chat-Rooms, das reicht aus um die offenen Anfrage fuer die man zustaendig ist anzuzeigen. -* Auch die Existenz eines 'done' Flags muesste ausreichen um zu erkennen das eine Anfrage 'done' ist, egal wer als +* Auch die Existenz eines Tags _'Done'_ muesste ausreichen um zu erkennen das eine Anfrage _'Done'_ ist, egal wer als 'Creator' eingetragen ist. * Die Diskussion ist aber eigentlich egal, denn wenn FE.pidCreator={{pIdFeUser:Y}} ist, werden keine Teams verwendet. @@ -333,8 +366,9 @@ TBD: was liefert der AJAX Call load.php zurueck wenn die 10 neuesten Messages, i * API: save.php * FormElement.id (zeigt direkt auf das FE.type=Chat Element) * Mode: 'Save Chat Message' -* Wird eine Message gespeichert und existiert zu dem Chat/Thread ein Done Flag und ist optionDoneResetOnNewMessage=1: - dann wird das Done Flag automatisch geloescht. +* Wird eine Message gespeichert und existiert zu dem Chat/Thread ein Tag _'Done'_ und ist + optionTagDoneResetOnNewMessage=1: + dann wird das Tag Done automatisch geloescht. ### Toggle Done Status @@ -351,7 +385,7 @@ QFQ interne Query fuer alle Messages (FE.thread=0): # # Alle DONEs (falls mehrere ein Done gesetzt haben) -SELECT c.pIdCreator, c.username FROM Chat AS c WHERE c.cIdTopic=$FE.cIdTopic AND c.xId=$FE.xId AND cDone.type='done' ORDER BY c.id +SELECT c.pIdCreator, c.username FROM Chat AS c WHERE c.cIdTopic=$FE.cIdTopic AND c.xId=$FE.xId AND cDone.type=_'Done'_ ORDER BY c.id # Alle Messages SELECT c.* @@ -372,15 +406,15 @@ SELECT c.*, GROUP_CONCAT(cDone.username) AS 'doneUsername' LEFT JOIN Chat AS cDone ON cDone.cIdTopic=$FE.cIdTopic AND cDone.xId=$FE.xId AND (cDone.cIdThread=c.id OR $FE.thread=0 ) - AND cDone.type='done' + AND cDone.type=_'Done'_ AND cDone.pIdCreator=c.pIdCreator - AND $FE.optionDone='all' OR ($FE.optionDone='my' AND cDone.pIdCreator=$FE.pIdCreator) + AND $FE.optionTagDone='all' OR ($FE.optionTagDone='my' AND cDone.pIdCreator=$FE.pIdCreator) WHERE c.cIdTopic=$FE.cIdTopic AND c.xId=$FE.xId ORDER BY c.id GROUP BY c.id </pre> -Problem: das done Flag soll gesetzt werden koennen fuer ein Team von Personen (=angenommen Dekant BEF hat mehrere +Problem: das Tag _'Done'_ soll gesetzt werden koennen fuer ein Team von Personen (=angenommen Dekant BEF hat mehrere Personen). In so einem Fall wird nicht die p.id einer realen Person im FE definiert, sondern die p.id einer anzulegen Pseudo Person (=Dekanat BEF). @@ -482,9 +516,9 @@ A * grIdSetGroupList: 120,121 - grIdSetGroupAccess * grIdCreatorGroupList -### Flag done +### Tag done -* Falls ein thread='done', ist das Textmessage Eingabe Feld muted und der 'Send' Button zeigt 'Reopen' an. +* Falls ein thread=_'Done'_, ist das Textmessage Eingabe Feld muted und der 'Send' Button zeigt 'Reopen' an. ### FormElement.parameter