~netlandish/links

599a912d10299c213b8a8365d8dc84036e59c35d — Yader Velasquez 9 months ago 63dc457
Improve tag parsing in resolvers
Include tag/exclude validation in helper function
Small fixes for tags UI

References: https://todo.code.netlandish.com/~netlandish/links/47
M api/graph/schema.resolvers.go => api/graph/schema.resolvers.go +3 -31
@@ 4744,18 4744,8 @@ func (r *queryResolver) GetOrgLinks(ctx context.Context, input *model.GetLinkInp
	}

	if (input.Tag != nil && *input.Tag != "") || (input.ExcludeTag != nil && *input.ExcludeTag != "") {
		var tagList = make([]string, 0)
		if input.Tag != nil && *input.Tag != "" {
			tagList = strings.Split(*input.Tag, ",")
		}

		var excludeTagList = make([]string, 0)
		if input.ExcludeTag != nil && *input.ExcludeTag != "" {
			excludeTagList = strings.Split(*input.ExcludeTag, ",")
		}
		// Filter based on tags
		f := links.NewTagQuery("tag_links", "org_link_id")
		subQText, subQVal, err := f.GetSubQuery(tagList, excludeTagList)
		subQText, subQVal, err := f.GetSubQuery(input.Tag, input.ExcludeTag)
		if err != nil {
			return nil, err
		}


@@ 5068,17 5058,8 @@ func (r *queryResolver) GetLinkShorts(ctx context.Context, input *model.GetLinkS
	}

	if (input.Tag != nil && *input.Tag != "") || (input.ExcludeTag != nil && *input.ExcludeTag != "") {
		var tagList = make([]string, 0)
		if input.Tag != nil && *input.Tag != "" {
			tagList = strings.Split(*input.Tag, ",")
		}

		var excludeTagList = make([]string, 0)
		if input.ExcludeTag != nil && *input.ExcludeTag != "" {
			excludeTagList = strings.Split(*input.ExcludeTag, ",")
		}
		f := links.NewTagQuery("tag_link_shorts", "link_short_id")
		subQText, subQVal, err := f.GetSubQuery(tagList, excludeTagList)
		subQText, subQVal, err := f.GetSubQuery(input.Tag, input.ExcludeTag)
		if err != nil {
			return nil, err
		}


@@ 5264,17 5245,8 @@ func (r *queryResolver) GetListings(ctx context.Context, input *model.GetListing
	}

	if (input.Tag != nil && *input.Tag != "") || (input.ExcludeTag != nil && *input.ExcludeTag != "") {
		var tagList = make([]string, 0)
		if input.Tag != nil && *input.Tag != "" {
			tagList = strings.Split(*input.Tag, ",")
		}

		var excludeTagList = make([]string, 0)
		if input.ExcludeTag != nil && *input.ExcludeTag != "" {
			excludeTagList = strings.Split(*input.ExcludeTag, ",")
		}
		f := links.NewTagQuery("tag_listings", "listing_id")
		subQText, subQVal, err := f.GetSubQuery(tagList, excludeTagList)
		subQText, subQVal, err := f.GetSubQuery(input.Tag, input.ExcludeTag)
		if err != nil {
			return nil, err
		}

M core/routes.go => core/routes.go +2 -2
@@ 1375,8 1375,8 @@ func (s *Service) OrgLinksList(c echo.Context) error {
		"org":              org,
		"isOrgLink":        isOrgLink,
		"canRead":          canRead,
		"tagFilter":        strings.Replace(tag, ",", ", ", -1),
		"excludeTagFilter": strings.Replace(excludeTag, ",", ", ", -1),
		"tagFilter":        tag,
		"excludeTagFilter": excludeTag,
		"navFlag":          navFlag,
		"advancedSearch":   advancedSearch,
		"hasUnreadFilter":  hasUnreadFilter,

M helpers.go => helpers.go +19 -1
@@ 721,7 721,25 @@ func NewTagQuery(t, c string) *TagQuery {
	}
}

func (t TagQuery) GetSubQuery(tags, excludeTags []string) (string, []interface{}, error) {
func (t TagQuery) GetSubQuery(inputTag, inputExcludeTag *string) (string, []interface{}, error) {
	var tags = make([]string, 0)
	if inputTag != nil && *inputTag != "" {
		tag := strings.Replace(*inputTag, " ", "", -1)
		if strings.HasSuffix(tag, ",") {
			tag = tag[:len(tag)-1]
		}
		tags = strings.Split(tag, ",")
	}

	var excludeTags = make([]string, 0)
	if inputExcludeTag != nil && *inputExcludeTag != "" {
		tag := strings.Replace(*inputExcludeTag, " ", "", -1)
		if strings.HasSuffix(tag, ",") {
			tag = tag[:len(tag)-1]
		}
		excludeTags = strings.Split(tag, ",")
	}

	subQOpts := &database.FilterOptions{
		Filter: sq.And{},
	}

M list/routes.go => list/routes.go +17 -10
@@ 987,12 987,6 @@ func (s *Service) ListingList(c echo.Context) error {
	pd.Data["delete"] = lt.Translate("Delete")
	pd.Data["analytics"] = lt.Translate("Analytics")

	gmap := gobwebs.Map{
		"pd":      pd,
		"org":     org,
		"navFlag": "listing",
	}

	type GraphQLResponse struct {
		Listings struct {
			Result   []models.Listing `json:"result"`


@@ 1006,8 1000,8 @@ func (s *Service) ListingList(c echo.Context) error {

	var result GraphQLResponse
	op := gqlclient.NewOperation(
		`query GetListings($orgSlug: String!, $after: Cursor, $before: Cursor, $tag: String) {
			getListings(input: {orgSlug: $orgSlug, after: $after, before: $before, tag: $tag}) {
		`query GetListings($orgSlug: String!, $after: Cursor, $before: Cursor, $tag: String, $excludeTag: String) {
			getListings(input: {orgSlug: $orgSlug, after: $after, before: $before, tag: $tag, excludeTag: $excludeTag}) {
				result {
					id
					title


@@ 1034,12 1028,17 @@ func (s *Service) ListingList(c echo.Context) error {

	op.Var("orgSlug", org.Slug)

	var tag string
	var tag, excludeTag string
	if c.QueryParam("tag") != "" {
		tag = c.QueryParam("tag")
		op.Var("tag", tag)
	}

	if c.QueryParam("exclude") != "" {
		excludeTag = c.QueryParam("exclude")
		op.Var("excludeTag", excludeTag)
	}

	if c.QueryParam("next") != "" {
		op.Var("after", c.QueryParam("next"))
	} else if c.QueryParam("prev") != "" {


@@ 1053,7 1052,15 @@ func (s *Service) ListingList(c echo.Context) error {
		}
		return err
	}
	gmap["lists"] = result.Listings.Result
	gmap := gobwebs.Map{
		"pd":               pd,
		"org":              org,
		"navFlag":          "listing",
		"lists":            result.Listings.Result,
		"tagFilter":        tag,
		"excludeTagFilter": excludeTag,
		"advancedSearch":   true,
	}
	if result.Listings.PageInfo.HasPrevPage {
		gmap["prevURL"] = links.GetPaginationParams("prev", tag, "", result.Listings.PageInfo.Cursor)
	}

M static/js/advancedsearch.js => static/js/advancedsearch.js +7 -4
@@ 76,17 76,20 @@ form.addEventListener("submit", function(e) {

    if (tagValue === "") {
        form.elements.tag.disabled = true;
    } else {
        tagValue = tagValue.split(", ").map(slugify).join(",");
    }
    else {
        tagValue = tagValue.split(",").map(slugify).join(", ");
        if (tagValue.endsWith(",")) {
            tagValue = tagValue.slice(0, -1);
        }
        form.elements.tag.value = tagValue;
    }

    if (excludeValue === "") {
        form.elements.exclude.disabled = true;
    } else {
        excludeValue = excludeValue.split(", ").join(",");
    }
    else {
        excludeValue = excludeValue.split(",").join(", ");
        if (excludeValue.endsWith(",")) {
            excludeValue = excludeValue.slice(0, -1);
        }

M templates/link_list.html => templates/link_list.html +1 -1
@@ 149,7 149,7 @@
                <small class="link-tag__item link-tag__item--simple">#{{.Name}}</small>
            {{else}}
                <a class="link-tag__item link-tag__item--simple"
                   href="{{if $.tagFilter}}?tag={{$.tagFilter}},{{.Slug}}{{if $.excludeTagFilter}}&exclude={{$.excludeTagFilter}}{{end}}{{else}}?tag={{.Slug}}{{if $.excludeTagFilter}}&exclude={{$.excludeTagFilter}}{{end}}{{end}}">#{{.Name}}</a>
                   href="{{if $.tagFilter}}?tag={{$.tagFilter}}, {{.Slug}}{{if $.excludeTagFilter}}&exclude={{$.excludeTagFilter}}{{end}}{{else}}?tag={{.Slug}}{{if $.excludeTagFilter}}&exclude={{$.excludeTagFilter}}{{end}}{{end}}">#{{.Name}}</a>
            {{end}}
          {{end}}
        </div>