From 9f323d019bb1e350bb50a8697240d17e032babc6 Mon Sep 17 00:00:00 2001 From: Jannis Mattheis Date: Tue, 3 Dec 2019 16:59:54 +0100 Subject: [PATCH] Make stringValue required --- hack/datagen/datagen.go | 24 +++++----------- model/tagdefinition.go | 11 -------- model/timespan.go | 2 +- schema.graphql | 17 ++++------- statistics/summary.go | 28 +++++++------------ statistics/summary_test.go | 12 ++++---- tag/create.go | 3 +- tag/create_test.go | 13 ++++----- tag/get_test.go | 4 +-- tag/suggest_test.go | 16 +++++------ tag/update.go | 3 +- tag/update_test.go | 10 +++---- test/db.go | 5 ++-- test/db_test.go | 3 +- timespan/convert.go | 10 +++---- timespan/remove_test.go | 6 +--- timespan/replace_tags_test.go | 16 +++++------ timespan/suggestvalue.go | 2 +- ui/src/common/Page.tsx | 8 ++++-- ui/src/dashboard/Entry/DashboardBarChart.tsx | 6 +--- ui/src/dashboard/Entry/DashboardLineChart.tsx | 6 +--- ui/src/dashboard/Entry/DashboardTable.tsx | 6 +--- ui/src/gql/dashboard.ts | 4 +-- ui/src/gql/statistics.ts | 4 +-- ui/src/gql/tags.ts | 13 +++------ ui/src/gql/timeSpan.ts | 14 +++++----- ui/src/tag/AddTagDialog.tsx | 20 ++----------- ui/src/tag/TagPage.tsx | 19 ++++--------- ui/src/tag/TagSelector.tsx | 5 ++-- ui/src/tag/suggest.ts | 2 +- ui/src/tag/tagSelectorEntry.ts | 15 ++++------ ui/src/timespan/Tracker.tsx | 2 +- ui/src/timespan/calendar/CalendarPage.tsx | 8 +++--- 33 files changed, 114 insertions(+), 203 deletions(-) diff --git a/hack/datagen/datagen.go b/hack/datagen/datagen.go index 02b478e..8c07809 100644 --- a/hack/datagen/datagen.go +++ b/hack/datagen/datagen.go @@ -40,37 +40,31 @@ func main() { log.Info().Msg("Creating Tags ...") db.Create(&model.TagDefinition{ - Type: model.TypeSingleValue, Key: "type", UserID: uID, Color: "#fff", }) db.Create(&model.TagDefinition{ - Type: model.TypeSingleValue, Key: "issue", UserID: uID, Color: "#fff", }) db.Create(&model.TagDefinition{ - Type: model.TypeSingleValue, Key: "meeting", UserID: uID, Color: "#fff", }) db.Create(&model.TagDefinition{ - Type: model.TypeSingleValue, Key: "with", UserID: uID, Color: "#fff", }) db.Create(&model.TagDefinition{ - Type: model.TypeSingleValue, Key: "misc", UserID: uID, Color: "#fff", }) db.Create(&model.TagDefinition{ - Type: model.TypeSingleValue, Key: "proj", UserID: uID, Color: "#fff", @@ -164,9 +158,9 @@ func generateIssueType(proj, t string) []timeSpan { for _, number := range numbers { result = append(result, timeSpan{ Tags: []model.TimeSpanTag{ - {Key: "proj", StringValue: &proj}, - {Key: "type", StringValue: p(t)}, - {Key: "issue", StringValue: p(fmt.Sprintf("%X-%d", proj, number))}, + {Key: "proj", StringValue: proj}, + {Key: "type", StringValue: t}, + {Key: "issue", StringValue: fmt.Sprintf("%X-%d", proj, number)}, }, Runtime: gotime.Hour * 24 * 12, }) @@ -181,8 +175,8 @@ func generateMeeting() []timeSpan { for _, name := range names { result = append(result, timeSpan{ Tags: []model.TimeSpanTag{ - {Key: "type", StringValue: p("meeting")}, - {Key: "meeting", StringValue: &name}, + {Key: "type", StringValue: "meeting"}, + {Key: "meeting", StringValue: name}, }, Runtime: gotime.Duration(-1), }) @@ -197,8 +191,8 @@ func generateSupport() []timeSpan { for _, name := range names { result = append(result, timeSpan{ Tags: []model.TimeSpanTag{ - {Key: "type", StringValue: p("support")}, - {Key: "with", StringValue: &name}, + {Key: "type", StringValue: "support"}, + {Key: "with", StringValue: name}, }, Runtime: gotime.Duration(-1), }) @@ -228,7 +222,3 @@ func noErr(err error) { func randInt(min int, max int) int { return min + rand.Intn(max-min) } - -func p(s string) *string { - return &s -} diff --git a/model/tagdefinition.go b/model/tagdefinition.go index 3635bdb..d7be704 100644 --- a/model/tagdefinition.go +++ b/model/tagdefinition.go @@ -5,16 +5,5 @@ type TagDefinition struct { Key string UserID int `gorm:"type:int REFERENCES users(id) ON DELETE CASCADE"` Color string - Type TagDefinitionType Usages int `gorm:"-"` } - -// TagDefinitionType describes a tag type. -type TagDefinitionType string - -const ( - // TypeNoValue used for tags without values - TypeNoValue TagDefinitionType = "novalue" - // TypeSingleValue used for tags with one value - TypeSingleValue TagDefinitionType = "singlevalue" -) diff --git a/model/timespan.go b/model/timespan.go index 30146d2..0269a0b 100644 --- a/model/timespan.go +++ b/model/timespan.go @@ -18,5 +18,5 @@ type TimeSpan struct { type TimeSpanTag struct { TimeSpanID int `gorm:"type:int REFERENCES time_spans(id) ON DELETE CASCADE"` Key string - StringValue *string + StringValue string } diff --git a/schema.graphql b/schema.graphql index a87f6f2..0b0a596 100644 --- a/schema.graphql +++ b/schema.graphql @@ -10,8 +10,8 @@ schema { } type RootMutation { - createTag(key: String!, color: String!, type: TagDefinitionType!): TagDefinition @hasRole(role: USER) - updateTag(key: String!, newKey: String, color: String!, type: TagDefinitionType!): TagDefinition @hasRole(role: USER) + createTag(key: String!, color: String!): TagDefinition @hasRole(role: USER) + updateTag(key: String!, newKey: String, color: String!): TagDefinition @hasRole(role: USER) removeTag(key: String!): TagDefinition @hasRole(role: USER) createUser(name: String!, pass: String!, admin: Boolean!): User @hasRole(role: ADMIN) @@ -138,16 +138,10 @@ scalar Time type TagDefinition { color: String! key: String! - type: TagDefinitionType! user: User! usages: Int! } -enum TagDefinitionType { - novalue - singlevalue -} - type User { admin: Boolean! id: Int! @@ -160,6 +154,7 @@ type TimeSpan { end: Time oldStart: Time tags: [TimeSpanTag!] + # TODO not nullable ^ } type PagedTimeSpans { @@ -169,12 +164,12 @@ type PagedTimeSpans { type TimeSpanTag { key: String! - stringValue: String + value: String! } input InputTimeSpanTag { key: String! - stringValue: String + value: String! } input StatInput { @@ -190,7 +185,7 @@ input Range { type StatisticsEntry { key: String! - stringValue: String + value: String! timeSpendInSeconds: Float! } diff --git a/statistics/summary.go b/statistics/summary.go index 8d96bfb..0f5bb91 100644 --- a/statistics/summary.go +++ b/statistics/summary.go @@ -87,18 +87,18 @@ func fillEmptyTags(statisticsEntries []*gqlmodel.RangedStatisticsEntries) { lookup := make(map[string]struct{}) for _, entry := range statisticsEntries { for _, statEntry := range entry.Entries { - lookup[key(statEntry.Key, statEntry.StringValue)] = struct{}{} + lookup[key(statEntry.Key, statEntry.Value)] = struct{}{} } } for _, entry := range statisticsEntries { existing := make(map[string]struct{}, len(lookup)) for _, statEntry := range entry.Entries { - existing[key(statEntry.Key, statEntry.StringValue)] = struct{}{} + existing[key(statEntry.Key, statEntry.Value)] = struct{}{} } for identifier := range lookup { if _, ok := existing[identifier]; !ok { key, value := extract(identifier) - entry.Entries = append(entry.Entries, &gqlmodel.StatisticsEntry{Key: key, StringValue: value, TimeSpendInSeconds: 0}) + entry.Entries = append(entry.Entries, &gqlmodel.StatisticsEntry{Key: key, Value: value, TimeSpendInSeconds: 0}) } } } @@ -129,7 +129,7 @@ type statReturn struct { QueryStart string QueryEnd string Key string - StringValue *string + StringValue string TimeSpendInSeconds float64 } @@ -150,7 +150,7 @@ func group(entries []statReturn) ([]*gqlmodel.RangedStatisticsEntries, error) { } stats[id].Entries = append(stats[id].Entries, &gqlmodel.StatisticsEntry{ Key: entry.Key, - StringValue: entry.StringValue, + Value: entry.StringValue, TimeSpendInSeconds: entry.TimeSpendInSeconds, }) } @@ -173,25 +173,17 @@ func build(tags []*gqlmodel.InputTimeSpanTag, noop string) (string, []interface{ var haveParams []interface{} for _, tag := range tags { have = append(have, "(tstx.key = ? AND tstx.string_value = ?)") - haveParams = append(haveParams, tag.Key, tag.StringValue) + haveParams = append(haveParams, tag.Key, tag.Value) } return strings.Join(have, " OR "), haveParams } -func key(key string, value *string) string { - if value == nil { - return key - } - return fmt.Sprintf("%s:%s", key, *value) +func key(key string, value string) string { + return fmt.Sprintf("%s:%s", key, value) } -func extract(id string) (string, *string) { +func extract(id string) (string, string) { split := strings.Split(id, ":") - if len(split) == 1 { - return split[0], nil - } - - value := split[1] - return split[0], &value + return split[0], split[1] } diff --git a/statistics/summary_test.go b/statistics/summary_test.go index 00a468b..140870d 100644 --- a/statistics/summary_test.go +++ b/statistics/summary_test.go @@ -275,8 +275,8 @@ func (e *testEntry) Ranges(ranges ...*gqlmodel.Range) *testEntry { func (e *testEntry) Include(includes ...model.TimeSpanTag) *testEntry { for _, entry := range includes { e.include = append(e.include, &gqlmodel.InputTimeSpanTag{ - Key: entry.Key, - StringValue: entry.StringValue, + Key: entry.Key, + Value: entry.StringValue, }) } return e @@ -284,8 +284,8 @@ func (e *testEntry) Include(includes ...model.TimeSpanTag) *testEntry { func (e *testEntry) Exclude(excludes ...model.TimeSpanTag) *testEntry { for _, entry := range excludes { e.exclude = append(e.exclude, &gqlmodel.InputTimeSpanTag{ - Key: entry.Key, - StringValue: entry.StringValue, + Key: entry.Key, + Value: entry.StringValue, }) } return e @@ -294,7 +294,7 @@ func (e *testEntry) Exclude(excludes ...model.TimeSpanTag) *testEntry { func tag(key string, value string) model.TimeSpanTag { return model.TimeSpanTag{ Key: key, - StringValue: &value, + StringValue: value, } } @@ -316,7 +316,7 @@ func result(start, stop string, entries ...*gqlmodel.StatisticsEntry) *gqlmodel. func entry(key string, value string, duration time.Duration) *gqlmodel.StatisticsEntry { return &gqlmodel.StatisticsEntry{ Key: key, - StringValue: &value, + Value: value, TimeSpendInSeconds: duration.Seconds(), } } diff --git a/tag/create.go b/tag/create.go index ddad98d..b1f4ee5 100644 --- a/tag/create.go +++ b/tag/create.go @@ -12,12 +12,11 @@ import ( ) // CreateTag creates a tag. -func (r *ResolverForTag) CreateTag(ctx context.Context, key string, color string, typeArg gqlmodel.TagDefinitionType) (*gqlmodel.TagDefinition, error) { +func (r *ResolverForTag) CreateTag(ctx context.Context, key string, color string) (*gqlmodel.TagDefinition, error) { userID := auth.GetUser(ctx).ID definition := &model.TagDefinition{ Key: strings.ToLower(key), Color: color, - Type: model.TagDefinitionType(typeArg), UserID: userID, } diff --git a/tag/create_test.go b/tag/create_test.go index 3f28d09..3f775be 100644 --- a/tag/create_test.go +++ b/tag/create_test.go @@ -17,19 +17,17 @@ func TestGQL_CreateTag_succeeds_addsTag(t *testing.T) { db.User(5) resolver := ResolverForTag{DB: db.DB} - tag, err := resolver.CreateTag(fake.User(5), "new tag", "#fff", gqlmodel.TagDefinitionTypeSinglevalue) + tag, err := resolver.CreateTag(fake.User(5), "new tag", "#fff") require.Nil(t, err) expected := &gqlmodel.TagDefinition{ Key: "new tag", Color: "#fff", - Type: gqlmodel.TagDefinitionTypeSinglevalue, } require.Equal(t, expected, tag) assertTagExist(t, db, model.TagDefinition{ Key: "new tag", Color: "#fff", - Type: model.TypeSingleValue, UserID: 5, }) assertTagCount(t, db, 1) @@ -39,10 +37,10 @@ func TestGQL_CreateTag_fails_tagAlreadyExists(t *testing.T) { db := test.InMemoryDB(t) defer db.Close() db.User(5) - db.Create(&model.TagDefinition{Key: "existing tag", Color: "#fff", Type: model.TypeSingleValue, UserID: 5}) + db.Create(&model.TagDefinition{Key: "existing tag", Color: "#fff", UserID: 5}) resolver := ResolverForTag{DB: db.DB} - _, err := resolver.CreateTag(fake.User(5), "existing tag", "#fff", gqlmodel.TagDefinitionTypeSinglevalue) + _, err := resolver.CreateTag(fake.User(5), "existing tag", "#fff") require.EqualError(t, err, "tag with key 'existing tag' does already exist") assertTagCount(t, db, 1) @@ -53,17 +51,16 @@ func TestGQL_CreateTag_succeeds_existingTagForOtherUser(t *testing.T) { defer db.Close() db.User(4) db.User(5) - db.Create(&model.TagDefinition{Key: "existing tag", Color: "#fff", Type: model.TypeSingleValue, UserID: 4}) + db.Create(&model.TagDefinition{Key: "existing tag", Color: "#fff", UserID: 4}) resolver := ResolverForTag{DB: db.DB} - _, err := resolver.CreateTag(fake.User(5), "existing tag", "#xxx", gqlmodel.TagDefinitionTypeSinglevalue) + _, err := resolver.CreateTag(fake.User(5), "existing tag", "#xxx") assert.Nil(t, err) assertTagCount(t, db, 2) assertTagExist(t, db, model.TagDefinition{ Key: "existing tag", Color: "#xxx", - Type: model.TypeSingleValue, UserID: 5, }) } diff --git a/tag/get_test.go b/tag/get_test.go index 71b155e..4515987 100644 --- a/tag/get_test.go +++ b/tag/get_test.go @@ -29,8 +29,8 @@ func TestGQL_Tags(t *testing.T) { require.Nil(t, err) expected := []*gqlmodel.TagDefinition{ - {Key: "my tag", Type: gqlmodel.TagDefinitionTypeSinglevalue, Usages: 3}, - {Key: "my tag 2", Type: gqlmodel.TagDefinitionTypeSinglevalue, Usages: 2}, + {Key: "my tag", Usages: 3}, + {Key: "my tag 2", Usages: 2}, } require.Equal(t, expected, tags) } diff --git a/tag/suggest_test.go b/tag/suggest_test.go index c415439..0fec41b 100644 --- a/tag/suggest_test.go +++ b/tag/suggest_test.go @@ -16,17 +16,17 @@ func TestGQL_SuggestTag_matchesTags(t *testing.T) { db.User(1) db.User(2) resolver := ResolverForTag{DB: db.DB} - db.Create(&model.TagDefinition{Key: "project", Color: "#fff", Type: model.TypeSingleValue, UserID: 1}) - db.Create(&model.TagDefinition{Key: "project2", Color: "#fff", Type: model.TypeSingleValue, UserID: 2}) - db.Create(&model.TagDefinition{Key: "priority", Color: "#fff", Type: model.TypeSingleValue, UserID: 1}) - db.Create(&model.TagDefinition{Key: "wood", Color: "#fff", Type: model.TypeSingleValue, UserID: 1}) + db.Create(&model.TagDefinition{Key: "project", Color: "#fff", UserID: 1}) + db.Create(&model.TagDefinition{Key: "project2", Color: "#fff", UserID: 2}) + db.Create(&model.TagDefinition{Key: "priority", Color: "#fff", UserID: 1}) + db.Create(&model.TagDefinition{Key: "wood", Color: "#fff", UserID: 1}) tags, err := resolver.SuggestTag(fake.User(1), "pr") require.Nil(t, err) expected := []*gqlmodel.TagDefinition{ - {Key: "project", Color: "#fff", Type: gqlmodel.TagDefinitionTypeSinglevalue}, - {Key: "priority", Color: "#fff", Type: gqlmodel.TagDefinitionTypeSinglevalue}, + {Key: "project", Color: "#fff"}, + {Key: "priority", Color: "#fff"}, } require.Equal(t, expected, tags) } @@ -36,8 +36,8 @@ func TestGQL_SuggestTag_noMatchingTags(t *testing.T) { defer db.Close() db.User(1) resolver := ResolverForTag{DB: db.DB} - db.Create(&model.TagDefinition{Key: "project", Color: "#fff", Type: model.TypeSingleValue, UserID: 1}) - db.Create(&model.TagDefinition{Key: "wood", Color: "#fff", Type: model.TypeSingleValue, UserID: 1}) + db.Create(&model.TagDefinition{Key: "project", Color: "#fff", UserID: 1}) + db.Create(&model.TagDefinition{Key: "wood", Color: "#fff", UserID: 1}) tags, err := resolver.SuggestTag(fake.User(1), "fire") diff --git a/tag/update.go b/tag/update.go index e2541cb..71733a2 100644 --- a/tag/update.go +++ b/tag/update.go @@ -12,7 +12,7 @@ import ( ) // UpdateTag updates a tag. -func (r *ResolverForTag) UpdateTag(ctx context.Context, key string, newKey *string, color string, typeArg gqlmodel.TagDefinitionType) (*gqlmodel.TagDefinition, error) { +func (r *ResolverForTag) UpdateTag(ctx context.Context, key string, newKey *string, color string) (*gqlmodel.TagDefinition, error) { tag := model.TagDefinition{} userID := auth.GetUser(ctx).ID if r.DB.Where(&model.TagDefinition{UserID: userID, Key: key}).Find(&tag).RecordNotFound() { @@ -24,7 +24,6 @@ func (r *ResolverForTag) UpdateTag(ctx context.Context, key string, newKey *stri newValue := model.TagDefinition{ Key: strings.ToLower(key), Color: color, - Type: model.TagDefinitionType(typeArg), UserID: userID, } diff --git a/tag/update_test.go b/tag/update_test.go index 2100880..92e6077 100644 --- a/tag/update_test.go +++ b/tag/update_test.go @@ -24,12 +24,11 @@ func TestUpdate_withKey(t *testing.T) { resolver := ResolverForTag{DB: db.DB} newTagName := "mega" - tag, err := resolver.UpdateTag(fake.User(left.User.ID), "coolio", &newTagName, "#abc", gqlmodel.TagDefinitionTypeSinglevalue) + tag, err := resolver.UpdateTag(fake.User(left.User.ID), "coolio", &newTagName, "#abc") require.NoError(t, err) require.Equal(t, &gqlmodel.TagDefinition{ Color: "#abc", Key: "mega", - Type: gqlmodel.TagDefinitionTypeSinglevalue, }, tag) left.AssertHasTagDefinition("coolio", false).AssertHasTagDefinition("mega", true) right.AssertHasTagDefinition("coolio", true).AssertHasTagDefinition("mega", false) @@ -50,12 +49,11 @@ func TestUpdate_withoutKey(t *testing.T) { rightTs.Tag("coolio", "mama") resolver := ResolverForTag{DB: db.DB} - tag, err := resolver.UpdateTag(fake.User(left.User.ID), "coolio", nil, "#abc", gqlmodel.TagDefinitionTypeSinglevalue) + tag, err := resolver.UpdateTag(fake.User(left.User.ID), "coolio", nil, "#abc") require.NoError(t, err) assert.Equal(t, &gqlmodel.TagDefinition{ Color: "#abc", Key: "coolio", - Type: gqlmodel.TagDefinitionTypeSinglevalue, }, tag) } @@ -72,7 +70,7 @@ func TestUpdate_dashboardEntryKey(t *testing.T) { newTag := "yes" resolver := ResolverForTag{DB: db.DB} - _, err := resolver.UpdateTag(fake.User(left.User.ID), "coolio", &newTag, "#abc", gqlmodel.TagDefinitionTypeSinglevalue) + _, err := resolver.UpdateTag(fake.User(left.User.ID), "coolio", &newTag, "#abc") require.NoError(t, err) db.Find(&entry) @@ -89,7 +87,7 @@ func TestUpdate_noPermissions(t *testing.T) { rightTs.Tag("coolio", "mama") resolver := ResolverForTag{DB: db.DB} - _, err := resolver.UpdateTag(fake.User(left.User.ID), "coolio", nil, "#abc", gqlmodel.TagDefinitionTypeSinglevalue) + _, err := resolver.UpdateTag(fake.User(left.User.ID), "coolio", nil, "#abc") require.EqualError(t, err, "tag with key 'coolio' does not exist") right.AssertHasTagDefinition("coolio", true) } diff --git a/test/db.go b/test/db.go index e1c3316..2514b80 100644 --- a/test/db.go +++ b/test/db.go @@ -59,7 +59,6 @@ func (d *UserWithDatabase) NewTagDefinition(key string) model.TagDefinition { tagDefinition := model.TagDefinition{ UserID: d.User.ID, Key: key, - Type: model.TypeSingleValue, } d.Create(&tagDefinition) return tagDefinition @@ -223,7 +222,7 @@ type TimeSpanWithDatabase struct { // AssertHasTag asserts if the tag exists or not. func (d *TimeSpanWithDatabase) AssertHasTag(key, value string, exist bool) *TimeSpanWithDatabase { existActual := !d.DB. - Where(&model.TimeSpanTag{Key: key, StringValue: &value, TimeSpanID: d.TimeSpan.ID}). + Where(&model.TimeSpanTag{Key: key, StringValue: value, TimeSpanID: d.TimeSpan.ID}). Find(new(model.TimeSpanTag)). RecordNotFound() assert.True(d.t, exist == existActual) @@ -255,7 +254,7 @@ func (d *TimeSpanWithDatabase) Tag(key string, stringValue string) *TimeSpanWith tag := model.TimeSpanTag{ TimeSpanID: d.TimeSpan.ID, Key: key, - StringValue: &stringValue, + StringValue: stringValue, } d.TimeSpan.Tags = append(d.TimeSpan.Tags, tag) d.DB.Save(tag) diff --git a/test/db_test.go b/test/db_test.go index 652ba71..5f8cdc8 100644 --- a/test/db_test.go +++ b/test/db_test.go @@ -56,7 +56,6 @@ func TestDatabase(t *testing.T) { db.Find(&devices) assert.Equal(t, expectedDevices, devices) - value := "def" expectedTimeSpans := []model.TimeSpan{{ ID: 1, UserID: 1, @@ -66,7 +65,7 @@ func TestDatabase(t *testing.T) { EndUTC: test.TimeP("2009-06-30T18:40:00Z"), Tags: []model.TimeSpanTag{{ Key: "abc", - StringValue: &value, + StringValue: "def", TimeSpanID: 1, }}, }} diff --git a/timespan/convert.go b/timespan/convert.go index 949f261..3395230 100644 --- a/timespan/convert.go +++ b/timespan/convert.go @@ -53,8 +53,8 @@ func tagsToExternal(tags []model.TimeSpanTag) []*gqlmodel.TimeSpanTag { result := []*gqlmodel.TimeSpanTag{} for _, tag := range tags { result = append(result, &gqlmodel.TimeSpanTag{ - Key: tag.Key, - StringValue: tag.StringValue, + Key: tag.Key, + Value: tag.StringValue, }) } return result @@ -71,7 +71,7 @@ func tagsToInternal(gqls []*gqlmodel.InputTimeSpanTag) []model.TimeSpanTag { func tagToInternal(gqls gqlmodel.InputTimeSpanTag) model.TimeSpanTag { return model.TimeSpanTag{ Key: gqls.Key, - StringValue: gqls.StringValue, + StringValue: gqls.Value, } } @@ -79,8 +79,8 @@ func tagsToInputTag(tags []model.TimeSpanTag) []*gqlmodel.InputTimeSpanTag { result := make([]*gqlmodel.InputTimeSpanTag, 0) for _, tag := range tags { result = append(result, &gqlmodel.InputTimeSpanTag{ - Key: tag.Key, - StringValue: tag.StringValue, + Key: tag.Key, + Value: tag.StringValue, }) } return result diff --git a/timespan/remove_test.go b/timespan/remove_test.go index 1c0a017..fab58d8 100644 --- a/timespan/remove_test.go +++ b/timespan/remove_test.go @@ -26,7 +26,7 @@ func TestRemoveTimeSpan_succeeds_removesTimeSpan(t *testing.T) { Start: test.ModelTime("2019-06-11T18:00:00Z"), End: test.ModelTimeP("2019-06-11T18:00:00Z"), Tags: []*gqlmodel.TimeSpanTag{ - {Key: "hello", StringValue: ps("world")}, + {Key: "hello", Value: "world"}, }, } require.Equal(t, expected, actual) @@ -76,7 +76,3 @@ func TestRemoveTimeSpan_fails_noPermission(t *testing.T) { _, err := resolver.RemoveTimeSpan(fake.User(5), 1) require.EqualError(t, err, "timespan with id 1 does not exist") } - -func ps(s string) *string { - return &s -} diff --git a/timespan/replace_tags_test.go b/timespan/replace_tags_test.go index e45189d..093923c 100644 --- a/timespan/replace_tags_test.go +++ b/timespan/replace_tags_test.go @@ -21,8 +21,8 @@ func TestReplace_simple(t *testing.T) { resolver := ResolverForTimeSpan{DB: db.DB} _, err := resolver.ReplaceTimeSpanTags(fake.User(1), - gqlmodel.InputTimeSpanTag{Key: "old", StringValue: ps("1")}, - gqlmodel.InputTimeSpanTag{Key: "new", StringValue: ps("1.0")}, + gqlmodel.InputTimeSpanTag{Key: "old", Value: "1"}, + gqlmodel.InputTimeSpanTag{Key: "new", Value: "1.0"}, gqlmodel.InputReplaceOptions{Override: gqlmodel.OverrideModeDiscard}) require.NoError(t, err) @@ -43,8 +43,8 @@ func TestReplace_discard(t *testing.T) { resolver := ResolverForTimeSpan{DB: db.DB} _, err := resolver.ReplaceTimeSpanTags(fake.User(1), - gqlmodel.InputTimeSpanTag{Key: "old", StringValue: ps("1")}, - gqlmodel.InputTimeSpanTag{Key: "new", StringValue: ps("1.0")}, + gqlmodel.InputTimeSpanTag{Key: "old", Value: "1"}, + gqlmodel.InputTimeSpanTag{Key: "new", Value: "1.0"}, gqlmodel.InputReplaceOptions{Override: gqlmodel.OverrideModeDiscard}) require.NoError(t, err) @@ -66,8 +66,8 @@ func TestReplace_override(t *testing.T) { resolver := ResolverForTimeSpan{DB: db.DB} _, err := resolver.ReplaceTimeSpanTags(fake.User(1), - gqlmodel.InputTimeSpanTag{Key: "old", StringValue: ps("1")}, - gqlmodel.InputTimeSpanTag{Key: "new", StringValue: ps("1.0")}, + gqlmodel.InputTimeSpanTag{Key: "old", Value: "1"}, + gqlmodel.InputTimeSpanTag{Key: "new", Value: "1.0"}, gqlmodel.InputReplaceOptions{Override: gqlmodel.OverrideModeOverride}) require.NoError(t, err) @@ -96,8 +96,8 @@ func TestReplace_multiuser(t *testing.T) { resolver := ResolverForTimeSpan{DB: db.DB} _, err := resolver.ReplaceTimeSpanTags(fake.User(1), - gqlmodel.InputTimeSpanTag{Key: "old", StringValue: ps("1")}, - gqlmodel.InputTimeSpanTag{Key: "new", StringValue: ps("1.0")}, + gqlmodel.InputTimeSpanTag{Key: "old", Value: "1"}, + gqlmodel.InputTimeSpanTag{Key: "new", Value: "1.0"}, gqlmodel.InputReplaceOptions{Override: gqlmodel.OverrideModeOverride}) require.NoError(t, err) diff --git a/timespan/suggestvalue.go b/timespan/suggestvalue.go index 97f2dc2..b98fdc9 100644 --- a/timespan/suggestvalue.go +++ b/timespan/suggestvalue.go @@ -20,7 +20,7 @@ func (r *ResolverForTimeSpan) SuggestTagValue(ctx context.Context, key string, q Find(&suggestions) var result []string for _, value := range suggestions { - result = append(result, *value.StringValue) + result = append(result, value.StringValue) } return result, find.Error diff --git a/ui/src/common/Page.tsx b/ui/src/common/Page.tsx index c8cdefd..446fd0e 100644 --- a/ui/src/common/Page.tsx +++ b/ui/src/common/Page.tsx @@ -35,7 +35,7 @@ import {CurrentUser} from '../gql/__generated__/CurrentUser'; import * as gqlDashboard from '../gql/dashboard'; import {Dashboards} from '../gql/__generated__/Dashboards'; import makeStyles from '@material-ui/core/styles/makeStyles'; -import {Route, RouteChildrenProps, Switch} from "react-router"; +import {Route, RouteChildrenProps, Switch} from 'react-router'; const drawerWidth = 240; @@ -242,8 +242,10 @@ export const Page: React.FC = ({children}) => { {(props: RouteChildrenProps<{id: string}>) => { - const db = dashboards.find(dashboard => dashboard.id === parseInt(props.match!.params.id, 10)); - return "Dashboards / " + (db ? db.name : '...'); + const db = dashboards.find( + (dashboard) => dashboard.id === parseInt(props.match!.params.id, 10) + ); + return 'Dashboards / ' + (db ? db.name : '...'); }} diff --git a/ui/src/dashboard/Entry/DashboardBarChart.tsx b/ui/src/dashboard/Entry/DashboardBarChart.tsx index 8928e37..01b9678 100644 --- a/ui/src/dashboard/Entry/DashboardBarChart.tsx +++ b/ui/src/dashboard/Entry/DashboardBarChart.tsx @@ -27,11 +27,7 @@ export const DashboardBarChart: React.FC = ({entries, in start: entry.start, end: entry.end, data: entry.entries!.reduce((all: Record, current) => { - if (current.stringValue === null) { - return {...all, [current.key]: current.timeSpendInSeconds}; - } else { - return {...all, [current.key + ':' + current.stringValue]: current.timeSpendInSeconds}; - } + return {...all, [current.key + ':' + current.value]: current.timeSpendInSeconds}; }, {}), }; }) diff --git a/ui/src/dashboard/Entry/DashboardLineChart.tsx b/ui/src/dashboard/Entry/DashboardLineChart.tsx index 7d98418..3cc1936 100644 --- a/ui/src/dashboard/Entry/DashboardLineChart.tsx +++ b/ui/src/dashboard/Entry/DashboardLineChart.tsx @@ -26,11 +26,7 @@ export const DashboardLineChart: React.FC = ({entries, i start: entry.start, end: entry.end, data: entry.entries!.reduce((all: Record, current) => { - if (current.stringValue === null) { - return {...all, [current.key]: current.timeSpendInSeconds}; - } else { - return {...all, [current.key + ':' + current.stringValue]: current.timeSpendInSeconds}; - } + return {...all, [current.key + ':' + current.value]: current.timeSpendInSeconds}; }, {}), }; }) diff --git a/ui/src/dashboard/Entry/DashboardTable.tsx b/ui/src/dashboard/Entry/DashboardTable.tsx index b963727..368b391 100644 --- a/ui/src/dashboard/Entry/DashboardTable.tsx +++ b/ui/src/dashboard/Entry/DashboardTable.tsx @@ -26,11 +26,7 @@ export const DashboardTable: React.FC = ({entries, interval start: entry.start, end: entry.end, data: entry.entries!.reduce((all: Record, current) => { - if (current.stringValue === null) { - return {...all, [current.key]: current.timeSpendInSeconds}; - } else { - return {...all, [current.key + ':' + current.stringValue]: current.timeSpendInSeconds}; - } + return {...all, [current.key + ':' + current.value]: current.timeSpendInSeconds}; }, {}), }; }) diff --git a/ui/src/gql/dashboard.ts b/ui/src/gql/dashboard.ts index 6585778..6ae792d 100644 --- a/ui/src/gql/dashboard.ts +++ b/ui/src/gql/dashboard.ts @@ -28,11 +28,11 @@ export const Dashboards = gql` tags excludeTags { key - stringValue + value } includeTags { key - stringValue + value } } pos { diff --git a/ui/src/gql/statistics.ts b/ui/src/gql/statistics.ts index 44666a8..4599b31 100644 --- a/ui/src/gql/statistics.ts +++ b/ui/src/gql/statistics.ts @@ -7,7 +7,7 @@ export const Stats = gql` end entries { key - stringValue + value timeSpendInSeconds } } @@ -20,7 +20,7 @@ export const Stats2 = gql` end entries { key - stringValue + value timeSpendInSeconds } } diff --git a/ui/src/gql/tags.ts b/ui/src/gql/tags.ts index 739b556..67682bd 100644 --- a/ui/src/gql/tags.ts +++ b/ui/src/gql/tags.ts @@ -5,7 +5,6 @@ export const SuggestTag = gql` tags: suggestTag(query: $query) { color key - type } } `; @@ -15,7 +14,6 @@ export const Tags = gql` tags { color key - type usages } } @@ -27,21 +25,19 @@ export const SuggestTagValue = gql` `; export const AddTag = gql` - mutation AddTag($name: String!, $color: String!, $type: TagDefinitionType!) { - createTag(key: $name, color: $color, type: $type) { + mutation AddTag($name: String!, $color: String!) { + createTag(key: $name, color: $color) { color key - type } } `; export const UpdateTag = gql` - mutation UpdateTag($key: String!, $newKey: String, $color: String!, $type: TagDefinitionType!) { - updateTag(key: $key, newKey: $newKey, color: $color, type: $type) { + mutation UpdateTag($key: String!, $newKey: String, $color: String!) { + updateTag(key: $key, newKey: $newKey, color: $color) { color key - type } } `; @@ -51,7 +47,6 @@ export const RemoveTag = gql` removeTag(key: $key) { color key - type } } `; diff --git a/ui/src/gql/timeSpan.ts b/ui/src/gql/timeSpan.ts index cfbdc52..2da310d 100644 --- a/ui/src/gql/timeSpan.ts +++ b/ui/src/gql/timeSpan.ts @@ -8,7 +8,7 @@ export const Trackers = gql` end tags { key - stringValue + value } oldStart } @@ -24,7 +24,7 @@ export const TimeSpansInRange = gql` end tags { key - stringValue + value } oldStart } @@ -46,7 +46,7 @@ export const TimeSpans = gql` end tags { key - stringValue + value } oldStart } @@ -67,7 +67,7 @@ export const StartTimer = gql` end tags { key - stringValue + value } oldStart } @@ -82,7 +82,7 @@ export const StopTimer = gql` end tags { key - stringValue + value } oldStart } @@ -97,7 +97,7 @@ export const AddTimeSpan = gql` end tags { key - stringValue + value } oldStart } @@ -112,7 +112,7 @@ export const UpdateTimeSpan = gql` end tags { key - stringValue + value } oldStart } diff --git a/ui/src/tag/AddTagDialog.tsx b/ui/src/tag/AddTagDialog.tsx index 995b81c..1352e43 100644 --- a/ui/src/tag/AddTagDialog.tsx +++ b/ui/src/tag/AddTagDialog.tsx @@ -6,11 +6,9 @@ import DialogActions from '@material-ui/core/DialogActions'; import DialogContent from '@material-ui/core/DialogContent'; import DialogContentText from '@material-ui/core/DialogContentText'; import DialogTitle from '@material-ui/core/DialogTitle'; -import {TagDefinitionType} from '../gql/__generated__/globalTypes'; import {SliderPicker} from 'react-color'; -import {InputLabel, MenuItem} from '@material-ui/core'; +import {InputLabel} from '@material-ui/core'; import FormControl from '@material-ui/core/FormControl'; -import Select from '@material-ui/core/Select'; import {MutationFetchResult} from 'react-apollo'; import {AddTag, AddTagVariables} from '../gql/__generated__/AddTag'; import * as gqlTags from '../gql/tags'; @@ -27,12 +25,11 @@ interface AddTagDialogProps { export const AddTagDialog: React.FC = ({close, open, initialName, onAdded = () => {}}) => { const [name, setName] = React.useState(initialName); const [color, setColor] = React.useState('#e6b3b3'); - const [type, setType] = React.useState(TagDefinitionType.singlevalue); const [addTag] = useMutation(gqlTags.AddTag, {refetchQueries: [{query: gqlTags.Tags}]}); const submit = (e: React.FormEvent) => { e.preventDefault(); - addTag({variables: {name, color, type}}).then((result: MutationFetchResult | void) => { + addTag({variables: {name, color}}).then((result: MutationFetchResult | void) => { close(); if (result && result.data && result.data.createTag) { onAdded(result.data.createTag); @@ -64,19 +61,6 @@ export const AddTagDialog: React.FC = ({close, open, initialN setColor(c.hex)} color={color} /> - - Type - -