// FindDashboards returns a list of dashboards that match filter and the total count of matching dashboards.
// Additional options provide pagination & sorting.
507073
func (s *DashboardService) FindDashboards(ctx context.Context, filter platform.DashboardFilter, opts platform.FindOptions) ([]*platform.Dashboard, int, error) {
	dashboards := []*platform.Dashboard{}
	url, err := newURL(s.Addr, dashboardsPath)

	if err != nil {
		return dashboards, 0, err
	}

	qp := url.Query()
	qp.Add("sortBy", opts.SortBy)
	for _, id := range filter.IDs {
		qp.Add("id", id.String())
	}
	url.RawQuery = qp.Encode()

	req, err := http.NewRequest("GET", url.String(), nil)
	if err != nil {
		return dashboards, 0, err
	}

	SetToken(s.Token, req)
	hc := newClient(url.Scheme, s.InsecureSkipVerify)

	resp, err := hc.Do(req)
	if err != nil {
		return dashboards, 0, err
	}

	if err := CheckError(resp, true); err != nil {
		return dashboards, 0, err
	}

	var dr getDashboardsResponse
	if err := json.NewDecoder(resp.Body).Decode(&dr); err != nil {
		return dashboards, 0, err
	}

	dashboards = dr.toPlatform()
	return dashboards, len(dashboards), nil
}
1036056
func (s *DashboardService) GetDashboardCellView(ctx context.Context, dashboardID, cellID platform.ID) (*platform.View, error) {
	u, err := newURL(s.Addr, cellViewPath(dashboardID, cellID))
	if err != nil {
		return nil, err
	}

	req, err := http.NewRequest("GET", u.String(), nil)
	if err != nil {
		return nil, err
	}

	req.Header.Set("Content-Type", "application/json")
	SetToken(s.Token, req)

	hc := newClient(u.Scheme, s.InsecureSkipVerify)

	resp, err := hc.Do(req)
	if err != nil {
		return nil, err
	}

	if err := CheckError(resp, true); err != nil {
		return nil, err
	}

	res := viewResponse{}
	if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	return &res.View, nil
}
426126
func (h *DashboardHandler) handleGetDashboardLog(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	req, err := decodeGetDashboardLogRequest(ctx, r)
	if err != nil {
		EncodeError(ctx, err, w)
		return
	}

	log, _, err := h.DashboardOperationLogService.GetDashboardOperationLog(ctx, req.DashboardID, req.opts)
	if err != nil {
		EncodeError(ctx, err, w)
		return
	}

	if err := encodeResponse(ctx, w, http.StatusOK, newDashboardLogResponse(req.DashboardID, log)); err != nil {
		logEncodingError(h.Logger, r, err)
		return
	}
}
589048
func NewDashboards(dir string, ids chronograf.ID, logger chronograf.Logger) chronograf.DashboardsStore {
	return &Dashboards{
		Dir:     dir,
		Load:    load,
		Create:  create,
		ReadDir: ioutil.ReadDir,
		Remove:  os.Remove,
		IDs:     ids,
		Logger:  logger,
	}
}
76032
func (s *Service) RemoveDashboardCell(ctx context.Context, dashboardID platform.ID, cellID platform.ID) error {
	op := OpPrefix + platform.OpRemoveDashboardCell
	d, err := s.FindDashboardByID(ctx, dashboardID)
	if err != nil {
		return &platform.Error{
			Err: err,
			Op:  op,
		}
	}

	idx := -1
	for i, cell := range d.Cells {
		if cell.ID == cellID {
			idx = i
			break
		}
	}
	if idx == -1 {
		return &platform.Error{
			Code: platform.ENotFound,
			Op:   op,
			Msg:  platform.ErrCellNotFound,
		}
	}

	if err := s.DeleteView(ctx, d.Cells[idx].ID); err != nil {
		return &platform.Error{
			Err: err,
			Op:  op,
		}
	}

	d.Cells = append(d.Cells[:idx], d.Cells[idx+1:]...)
	return s.PutDashboardWithMeta(ctx, d)

}
566822
func getDashboardContextUser(c *context.Context) *models.User {
	ctxUser := c.User
	orgName := c.Params(":org")
	if len(orgName) > 0 {
		// Organization.
		org, err := models.GetUserByName(orgName)
		if err != nil {
			c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
			return nil
		}
		ctxUser = org
	}
	c.Data["ContextUser"] = ctxUser

	if err := c.User.GetOrganizations(true); err != nil {
		c.Handle(500, "GetOrganizations", err)
		return nil
	}
	c.Data["Orgs"] = c.User.Orgs

	return ctxUser
}
971915
func SortDashboards(by string, ds []*Dashboard) {
	var sorter func(i, j int) bool
	switch by {
	case "CreatedAt":
		sorter = func(i, j int) bool {
			return ds[j].Meta.CreatedAt.After(ds[i].Meta.CreatedAt)
		}
	case "UpdatedAt":
		sorter = func(i, j int) bool {
			return ds[j].Meta.UpdatedAt.After(ds[i].Meta.UpdatedAt)
		}
	case "Name":
		sorter = func(i, j int) bool {
			return ds[i].Name < ds[j].Name
		}
	default:
		sorter = func(i, j int) bool {
			return ds[i].ID < ds[j].ID
		}
	}

	sort.Slice(ds, sorter)
}
327899
func NewDashboard(title string) *Dashboard {
	dash := &Dashboard{}
	dash.Data = simplejson.New()
	dash.Data.Set("title", title)
	dash.Title = title
	dash.Created = time.Now()
	dash.Updated = time.Now()
	dash.UpdateSlug()
	return dash
}
1039292
func GetDashboard(client ClientInterface, params url.Values) (*Dashboard, error) {
	if params.Get("offset") != "" && params.Get("since_id") != "" {
		return nil, errors.New("Cannot specify both offset and since_id")
	}

	response, err := client.GetWithParams("/user/dashboard", params)
	if err != nil {
		return nil, err
	}
	result := struct {
		Response struct {
			Posts []MiniPost `json:"posts"`
		} `json:"response"`
	}{}
	if err = json.Unmarshal(response.body, &result); err != nil {
		return nil, err
	}
	minis := result.Response.Posts
	full := struct {
		Response Dashboard `json:"response"`
	}{
		Response: Dashboard{
			client:   client,
			params:   params,
			byOffset: params.Get("offset") != "",
			bySince:  params.Get("since_id") != "",
		},
	}
	full.Response.Posts = makePostsFromMinis(minis, client)
	if err = json.Unmarshal(response.body, &full); err != nil {
		return nil, err
	}
	return &full.Response, nil
}
794309
func (cmd *CreateFolderCommand) GetDashboardModel(orgId int64, userId int64) *Dashboard {
	dashFolder := NewDashboardFolder(strings.TrimSpace(cmd.Title))
	dashFolder.OrgId = orgId
	dashFolder.SetUid(strings.TrimSpace(cmd.Uid))

	if userId == 0 {
		userId = -1
	}

	dashFolder.CreatedBy = userId
	dashFolder.UpdatedBy = userId
	dashFolder.UpdateSlug()

	return dashFolder
}
115146
func (s *DashboardService) UpdateDashboard(ctx context.Context, id influxdb.ID, upd influxdb.DashboardUpdate) (*influxdb.Dashboard, error) {
	b, err := s.s.FindDashboardByID(ctx, id)
	if err != nil {
		return nil, err
	}

	if err := authorizeWriteDashboard(ctx, b.OrganizationID, id); err != nil {
		return nil, err
	}

	return s.s.UpdateDashboard(ctx, id, upd)
}
644647
func (c *Client) GetDashboard() (*tumblr.Dashboard, error) {
	return c.GetDashboardWithParams(url.Values{})
}
504445
func ValidDashboardRequest(d *chronograf.Dashboard, defaultOrgID string) error {
	if d.Organization == "" {
		d.Organization = defaultOrgID
	}
	for i, c := range d.Cells {
		if err := ValidDashboardCellRequest(&c); err != nil {
			return err
		}
		d.Cells[i] = c
	}
	for _, t := range d.Templates {
		if err := ValidTemplateRequest(&t); err != nil {
			return err
		}
	}
	(*d) = DashboardDefaults(*d)
	return nil
}
727888
func (s *Service) ReplaceDashboard(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	idParam, err := paramID("id", r)
	if err != nil {
		msg := fmt.Sprintf("Could not parse dashboard ID: %s", err)
		Error(w, http.StatusInternalServerError, msg, s.Logger)
	}
	id := chronograf.DashboardID(idParam)

	_, err = s.Store.Dashboards(ctx).Get(ctx, id)
	if err != nil {
		Error(w, http.StatusNotFound, fmt.Sprintf("ID %d not found", id), s.Logger)
		return
	}

	var req chronograf.Dashboard
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		invalidJSON(w, s.Logger)
		return
	}
	req.ID = id

	defaultOrg, err := s.Store.Organizations(ctx).DefaultOrganization(ctx)
	if err != nil {
		unknownErrorWithMessage(w, err, s.Logger)
		return
	}

	if err := ValidDashboardRequest(&req, defaultOrg.ID); err != nil {
		invalidData(w, err, s.Logger)
		return
	}

	if err := s.Store.Dashboards(ctx).Update(ctx, req); err != nil {
		msg := fmt.Sprintf("Error updating dashboard ID %d: %v", id, err)
		Error(w, http.StatusInternalServerError, msg, s.Logger)
		return
	}

	res := newDashboardResponse(req)
	encodeJSON(w, http.StatusOK, res, s.Logger)
}
466047
func (s *Service) GetDashboardCellView(ctx context.Context, dashboardID, cellID influxdb.ID) (*influxdb.View, error) {
	var v *influxdb.View
	err := s.kv.View(ctx, func(tx Tx) error {
		view, err := s.findDashboardCellView(ctx, tx, dashboardID, cellID)
		if err != nil {
			return err
		}

		v = view
		return nil
	})

	if err != nil {
		return nil, &influxdb.Error{
			Err: err,
		}
	}

	return v, nil
}
445855
func GetDashboardVersion(query *m.GetDashboardVersionQuery) error {
	version := m.DashboardVersion{}
	has, err := x.Where("dashboard_version.dashboard_id=? AND dashboard_version.version=? AND dashboard.org_id=?", query.DashboardId, query.Version, query.OrgId).
		Join("LEFT", "dashboard", `dashboard.id = dashboard_version.dashboard_id`).
		Get(&version)

	if err != nil {
		return err
	}

	if !has {
		return m.ErrDashboardVersionNotFound
	}

	version.Data.Set("id", version.DashboardId)
	query.Result = &version
	return nil
}
634225
func (s *Service) forEachDashboard(ctx context.Context, tx Tx, descending bool, fn func(*influxdb.Dashboard) bool) error {
	b, err := tx.Bucket(dashboardBucket)
	if err != nil {
		return err
	}

	cur, err := b.Cursor()
	if err != nil {
		return err
	}

	var k, v []byte
	if descending {
		k, v = cur.Last()
	} else {
		k, v = cur.First()
	}

	for k != nil {
		d := &influxdb.Dashboard{}
		if err := json.Unmarshal(v, d); err != nil {
			return err
		}

		if !fn(d) {
			break
		}

		if descending {
			k, v = cur.Prev()
		} else {
			k, v = cur.Next()
		}
	}

	return nil
}