Skip to content

Commit

Permalink
Merge pull request #279 from jtooya/edit-DG
Browse files Browse the repository at this point in the history
Edit dg to include information on Import command
  • Loading branch information
jtooya authored Nov 12, 2024
2 parents 499bf9e + 093321b commit 133f48c
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 41 deletions.
83 changes: 78 additions & 5 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,11 @@ How the parsing works:
### Model component
**API** : [`Model.java`](https://github.com/AY2425S1-CS2103T-W12-3/tp/blob/master/src/main/java/seedu/address/model/Model.java)


<puml src="diagrams/ModelClassDiagram.puml" width="100%" />



The `Model` component,

* stores the address book data i.e., all `Person` objects (which are contained in a `UniquePersonList` object).
Expand All @@ -141,7 +143,7 @@ The `Model` component,

**API** : [`Storage.java`](https://github.com/AY2425S1-CS2103T-W12-3/tp/blob/master/src/main/java/seedu/address/storage/Storage.java)

<puml src="diagrams/StorageClassDiagram.puml" width="550" />
<puml src="diagrams/StorageClassDiagram.puml" width="700" />

The `Storage` component,
* can save both address book data and user preference data in JSON format, and read them back into corresponding objects.
Expand Down Expand Up @@ -187,6 +189,7 @@ The optional fields allow users to include more detailed information, making the

<puml src="diagrams/AddSequenceDiagram.puml" width="100%" />


#### Design Considerations

* **Field Flexibility**
Expand Down Expand Up @@ -231,6 +234,41 @@ The command format is as follows:<br>
* Invalid theme inputs raises clear errors, guiding users on valid options.
* `ThemePreference` manages file I/O errors with warnings, defaulting to "LIGHT" if any issues arise with loading or saving preferences.

### Import feature

#### Implementation

The import command allows users to import multiple contacts from a .csv file. The command allows for convenient distribution and importing of contacts. Contact distributors (e.g. course coordinators) can compile many contacts at a time (e.g. course TAs), with appropriate contact information and distributte them to users.<br>

The command format is as follows:<br>
`import​`

#### Key Components and Operations

* **Converter (CsvToJsonConverter)**
* The `Converter` component processes the `.csv` files to convert each file into a `.json` file. It first requests all the fields that compose a Person class. It then reads the `.csv` file headers for headers that match these fields (case-insensitive).
* It will then read the `.csv` file line by line, to parse each line under a valid header into a properly formatted `.json` object, which is then added to a jsonFile.
* It writes the contents of the `.csv` file into a `.json` file with the same name.
* After converting all `.csv` files, these individual `.json` files are put into an `ArrayList` of `.json` files and returned
* If the input format is invalid, a `ConverterException` is raised with an error message.
* This can occur in the case that the `.csv` is empty, or invalid, or the Import folder is empty or missing
* **Importer (jsonImporter)**
* The importer constructor takes in a `List<File>` that should contain the `.json` files to be imported.
* Upon calling `importAllJsonFiles()`, the importer will loop through each `.json` file in the list, parse them, then convert them to `AddressBook.class`, and add each `.json` file to the `model`.

<puml src="diagrams/ImportCommandSequenceDiagram.puml" width="1100" />
<puml src="diagrams/ConversionSequenceDiagram.puml" width="400" />
<puml src="diagrams/ImportSequenceDiagram.puml" width="1100" />

#### Design Considerations

* **Error Handling**
* Empty/Invalid contact information should be skipped or left empty, depending on whether the missing/invalid information is compulsory
* Non-compulsory fields such as `phone`, `email`, and `telegramHandle` require at least one entry, the rest can be left empty
* Upon encountering empty/invalid compulsory fields, such as `name` or `contactType`, these entries will be skipped by the `Converter`
* Missing Import folder should be re-initialised everytime the app is restarted
* Empty Import folder will result in an error being thrown


--------------------------------------------------------------------------------------------------------------------

Expand All @@ -250,10 +288,10 @@ The command format is as follows:<br>

**Target user profile**:

* university student who
* meets people from many different places (e.g. different classes, CCAs, student accomodation, etc.)
* have a need to manage a significant number of contacts
* prefer desktop apps over other types
* National University of Singapore (NUS) student who
* meets people from many different places (e.g. different classes, CCAs, student accommodation, etc.)
* has a need to manage a significant number of contacts
* prefers desktop apps over other types
* can type fast
* prefers typing to mouse interactions
* is reasonably comfortable using CLI apps
Expand Down Expand Up @@ -364,9 +402,11 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
Use case resumes at step 2.

* 4a. The entered data is invalid

* 4a1. UniLink shows an error message indicating fields that could be invalid.
* 4a2. User re-enters the new data


Steps 4a1-4a2 are repeated until the data entered is correct.

Use case resumes from step 5.
Expand Down Expand Up @@ -452,6 +492,39 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli

Use case ends.

**Use case: UC008 - Import contacts from .csv file**

**MSS**
1. User adds one or more .csv file(s) to Import folder
2. User requests to import contacts from .csv file(s)
3. UniLink imports contacts

**Extensions**

* 1a. There is no Import folder
* 1a1. UniLink shows error message
* 1a2. User restarts program to re-initialise Import folder

Use case resumes from step 1


* 1b. The .csv file is empty
* 1b1. UniLink shows error message
* 1b2. User attempts to import another .csv file

Use case resumes from step 1

* 3a. One (or more) of the contacts are invalid (Do not have valid contact info/ missing name/ missing contact type)
* 3a1. UniLink skips over invalid contacts

Use case resumes from step 3


* 3b. There are duplicate contacts/ contacts in .csv file already exist in addressbook
* 3b1. UniLink skips over duplicate contacts

Use case resumes from step 3

### Non-Functional Requirements

1. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage. (Efficiency and performance)
Expand Down
36 changes: 17 additions & 19 deletions docs/diagrams/AddSequenceDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,24 @@ end box

box Model MODEL_COLOR_T1
participant "m:Model" as Model MODEL_COLOR
participant "p:Person" as Person MODEL_COLOR
end box

box STORAGE STORAGE_COLOR_T1
participant ":JsonAddressBookStorage" as JsonAddressBookStorage STORAGE_COLOR
participant "j:JsonSerializableAddressBook" as JsonSerializableAddressBook STORAGE_COLOR
participant ":Storage" as JsonAddressBookStorage STORAGE_COLOR
end box

[-> LogicManager : execute("add n/John ct/work p/98765432")

note left of LogicManager
We'll henceforth refer to
the parameter part
(i.e. "n/John ct/work p/98765432")
of the command as [parameters]
end note

activate LogicManager

LogicManager -> AddressBookParser : parseCommand("add n/John ct/work p/98765432")
LogicManager -> AddressBookParser : parseCommand("add [parameters]")
activate AddressBookParser

create AddCommandParser
Expand All @@ -34,15 +40,14 @@ activate AddCommandParser
AddCommandParser --> AddressBookParser
deactivate AddCommandParser

AddressBookParser -> AddCommandParser : parse("n/John ct/work p/98765432")
AddressBookParser -> AddCommandParser : parse([parameters])
activate AddCommandParser

create Person
AddCommandParser -> Person
activate Person
AddCommandParser -> Model
activate Model

Person --> AddCommandParser : p
deactivate Person
Model --> AddCommandParser : p
deactivate Model

create AddCommand
AddCommandParser -> AddCommand : AddCommand(p)
Expand All @@ -60,7 +65,7 @@ destroy AddCommandParser
AddressBookParser --> LogicManager : a
deactivate AddressBookParser

LogicManager -> AddCommand : execute(m)
LogicManager -> AddCommand : execute(model)
activate AddCommand

AddCommand -> Model : addPerson(person)
Expand All @@ -82,14 +87,7 @@ deactivate AddCommand
LogicManager -> JsonAddressBookStorage : saveAddressBook(model.getAddressBook())
activate JsonAddressBookStorage

create JsonSerializableAddressBook
JsonAddressBookStorage -> JsonSerializableAddressBook
activate JsonSerializableAddressBook

JsonSerializableAddressBook --> JsonAddressBookStorage : j
deactivate JsonSerializableAddressBook

JsonAddressBookStorage --> LogicManager : j
JsonAddressBookStorage --> LogicManager
deactivate JsonAddressBookStorage

[<--LogicManager
Expand Down
22 changes: 22 additions & 0 deletions docs/diagrams/ConversionSequenceDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@startuml
!include style.puml
skinparam ArrowFontStyle plain
skinparam ArrowColor blue
group sd Conversion
participant "Converter:CsvToJsonConverter" as Converter STORAGE_COLOR

[-> Converter:convertAllCsvFiles()
activate Converter

Converter -> Converter: findAllCsvFiles

loop until all csv files converted
Converter -> Converter:convertCsvFile
Converter -> Converter:jsonFiles.add(csvFileConvertedtoJson)
end

Converter -->[ :List<File> jsonFiles
deactivate Converter
end

@enduml
74 changes: 74 additions & 0 deletions docs/diagrams/ImportCommandSequenceDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
@startuml
!include style.puml
skinparam ArrowFontStyle plain
skinparam ArrowColor blue

box Logic LOGIC_COLOR_T1
participant ":LogicManager" as LogicManager LOGIC_COLOR
participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
participant "i:ImportCommand" as ImportCommand LOGIC_COLOR
participant "r:CommandResult" as CommandResult LOGIC_COLOR
end box


box STORAGE STORAGE_COLOR_T1
participant "converter:CsvToJsonConverter" as CsvToJsonConverter STORAGE_COLOR
participant "importer:JsonImporter" as JsonImporter STORAGE_COLOR
end box

[-> LogicManager : execute("import")

activate LogicManager

LogicManager -> AddressBookParser : parseCommand("import")
activate AddressBookParser

create ImportCommand
AddressBookParser -> ImportCommand : ImportCommand()
activate ImportCommand

ImportCommand --> AddressBookParser : i
deactivate ImportCommand

AddressBookParser --> LogicManager : i
deactivate AddressBookParser

LogicManager -> ImportCommand : execute(model)
activate ImportCommand

create CsvToJsonConverter
ImportCommand -> CsvToJsonConverter: new CsvToJsonConverter(directory)
activate CsvToJsonConverter

CsvToJsonConverter --> ImportCommand
deactivate CsvToJsonConverter

ImportCommand -> CsvToJsonConverter :convertAllCsvFiles()
ref over CsvToJsonConverter : Conversion
CsvToJsonConverter --> ImportCommand: List<File> jsonFiles

create JsonImporter
ImportCommand -> JsonImporter : new JsonImporter(List<File> jsonFiles)
activate JsonImporter

JsonImporter --> ImportCommand
deactivate JsonImporter

ImportCommand -> JsonImporter: importAllJsonFiles(model)
ref over JsonImporter : Importing
JsonImporter --> ImportCommand : newModel

create CommandResult
ImportCommand -> CommandResult
activate CommandResult

CommandResult --> ImportCommand : r
deactivate CommandResult

ImportCommand --> LogicManager : r
deactivate ImportCommand


[<--LogicManager
deactivate LogicManager
@enduml
47 changes: 47 additions & 0 deletions docs/diagrams/ImportSequenceDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
@startuml
!include style.puml
skinparam ArrowFontStyle plain
skinparam ArrowColor blue
group sd Importing
participant ":JsonImporter" as Importer STORAGE_COLOR
participant ":JsonUtil" as Util #grey
participant "j:jsonSerializableAddressBook" as addressBook STORAGE_COLOR
participant "model:Model" as model MODEL_COLOR

[-> Importer : importAllJsonFiles(model)
activate Importer

loop Until all json files imported
Importer -> Importer:importJsonFile(jsonFile, model)
activate Importer
Importer -> Util : readJsonFile(filePath, JsonSerializableAddressBook.class)
activate Util
create addressBook
Util --> addressBook
activate addressBook
addressBook ---> Util
deactivate addressBook
Util ---> Importer:j


Importer -> addressBook: j.toModelType()
activate addressBook
addressBook --> Importer:jsonAddressBook
deactivate addressBook
Importer -> model : addAllPersons(addressBook)
model --> Importer: newModel
Importer -> Importer: newModel
deactivate Importer
'Hidden arrow to format loop box better.
Importer -[hidden]-> Importer



end
Importer -->[: newModel
deactivate Importer
end



@enduml
7 changes: 4 additions & 3 deletions docs/diagrams/ModelClassDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Class TelegramHandle
Class Remark
Class Tag

note "A person must have at least one of Phone, Email or TelegramHandle" as N2

Class I #FFFFFF
}

Expand Down Expand Up @@ -56,7 +58,6 @@ Name -[hidden]right-> Phone

ModelManager --> "~* filtered" Person

note right of Person
A person must have at least one of Phone, Email or TelegramHandle
end note

N2 .. Person
@enduml
2 changes: 1 addition & 1 deletion docs/diagrams/SwitchThemeSequenceDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ destroy SwitchThemeCommandParser
AddressBookParser --> LogicManager : s
deactivate AddressBookParser

LogicManager -> SwitchThemeCommand : execute(m)
LogicManager -> SwitchThemeCommand : execute(model)
activate SwitchThemeCommand

SwitchThemeCommand -> ThemeController : switchTheme("dark")
Expand Down
Loading

0 comments on commit 133f48c

Please sign in to comment.